* src/SDCCast.c (decorateType): fix for RFE 1475742, optimize 'ifx (op == 0)' resp...
[fw/sdcc] / src / SDCCast.c
1 /*-------------------------------------------------------------------------
2   SDCCast.c - source file for parser support & all ast related routines
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #define DEBUG_CF(x) /* puts(x); */
26
27 #include "common.h"
28
29 int currLineno = 0;
30 set *astList = NULL;
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
33 int labelKey = 1;
34
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
47 #define ALLOCATE 1
48 #define DEALLOCATE 2
49
50 int noLineno = 0;
51 int noAlloc = 0;
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *, RESULT_TYPE);
59 ast *optimizeGetAbit (ast *, RESULT_TYPE);
60 ast *optimizeGetByte (ast *, RESULT_TYPE);
61 ast *optimizeGetWord (ast *, RESULT_TYPE);
62 static ast *backPatchLabels (ast *, symbol *, symbol *);
63 void PA(ast *t);
64 int inInitMode = 0;
65 memmap *GcurMemmap=NULL;  /* points to the memmap that's currently active */
66 FILE *codeOutFile;
67 int
68 ptt (ast * tree)
69 {
70   printTypeChain (tree->ftype, stdout);
71   return 0;
72 }
73
74
75 /*-----------------------------------------------------------------*/
76 /* newAst - creates a fresh node for an expression tree            */
77 /*-----------------------------------------------------------------*/
78 static ast *
79 newAst_ (unsigned type)
80 {
81   ast *ex;
82   static int oldLineno = 0;
83
84   ex = Safe_alloc ( sizeof (ast));
85
86   ex->type = type;
87   ex->lineno = (noLineno ? oldLineno : mylineno);
88   ex->filename = currFname;
89   ex->level = NestLevel;
90   ex->block = currBlockno;
91   ex->initMode = inInitMode;
92   ex->seqPoint = seqPointNo;
93   return ex;
94 }
95
96 ast *
97 newAst_VALUE (value * val)
98 {
99   ast *ex = newAst_ (EX_VALUE);
100   ex->opval.val = val;
101   return ex;
102 }
103
104 ast *
105 newAst_OP (unsigned op)
106 {
107   ast *ex = newAst_ (EX_OP);
108   ex->opval.op = op;
109   return ex;
110 }
111
112 ast *
113 newAst_LINK (sym_link * val)
114 {
115   ast *ex = newAst_ (EX_LINK);
116   ex->opval.lnk = val;
117   return ex;
118 }
119
120 /*-----------------------------------------------------------------*/
121 /* newNode - creates a new node                                    */
122 /*-----------------------------------------------------------------*/
123 ast *
124 newNode (long op, ast * left, ast * right)
125 {
126   ast *ex;
127
128   ex = newAst_OP (op);
129   ex->left = left;
130   ex->right = right;
131
132   return ex;
133 }
134
135 /*-----------------------------------------------------------------*/
136 /* newIfxNode - creates a new Ifx Node                             */
137 /*-----------------------------------------------------------------*/
138 ast *
139 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 {
141   ast *ifxNode;
142
143   /* if this is a literal then we already know the result */
144   if (condAst->etype && IS_LITERAL (condAst->etype))
145     {
146       /* then depending on the expression value */
147       if (floatFromVal (condAst->opval.val))
148         ifxNode = newNode (GOTO,
149                            newAst_VALUE (symbolVal (trueLabel)),
150                            NULL);
151       else
152         ifxNode = newNode (GOTO,
153                            newAst_VALUE (symbolVal (falseLabel)),
154                            NULL);
155     }
156   else
157     {
158       ifxNode = newNode (IFX, condAst, NULL);
159       ifxNode->trueLabel = trueLabel;
160       ifxNode->falseLabel = falseLabel;
161     }
162
163   return ifxNode;
164 }
165
166 /*-----------------------------------------------------------------*/
167 /* copyAstValues - copies value portion of ast if needed     */
168 /*-----------------------------------------------------------------*/
169 void
170 copyAstValues (ast * dest, ast * src)
171 {
172   switch (src->opval.op)
173     {
174     case BLOCK:
175       dest->values.sym = copySymbolChain (src->values.sym);
176       break;
177
178     case SWITCH:
179       dest->values.switchVals.swVals =
180         copyValue (src->values.switchVals.swVals);
181       dest->values.switchVals.swDefault =
182         src->values.switchVals.swDefault;
183       dest->values.switchVals.swNum =
184         src->values.switchVals.swNum;
185       break;
186
187     case INLINEASM:
188       dest->values.inlineasm =  Safe_strdup(src->values.inlineasm);
189       break;
190
191     case ARRAYINIT:
192         dest->values.constlist = copyLiteralList(src->values.constlist);
193         break;
194
195     case FOR:
196       AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
197       AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
198       AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
199       AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
200       AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
201       AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
202       AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
203     }
204
205 }
206
207 /*-----------------------------------------------------------------*/
208 /* copyAst - makes a copy of a given astession                     */
209 /*-----------------------------------------------------------------*/
210 ast *
211 copyAst (ast * src)
212 {
213   ast *dest;
214
215   if (!src)
216     return NULL;
217
218   dest = Safe_alloc ( sizeof (ast));
219
220   dest->type = src->type;
221   dest->lineno = src->lineno;
222   dest->level = src->level;
223   dest->funcName = src->funcName;
224   dest->reversed = src->reversed;
225
226   if (src->ftype)
227     dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
228
229   /* if this is a leaf */
230   /* if value */
231   if (src->type == EX_VALUE)
232     {
233       dest->opval.val = copyValue (src->opval.val);
234       goto exit;
235     }
236
237   /* if link */
238   if (src->type == EX_LINK)
239     {
240       dest->opval.lnk = copyLinkChain (src->opval.lnk);
241       goto exit;
242     }
243
244   dest->opval.op = src->opval.op;
245
246   /* if this is a node that has special values */
247   copyAstValues (dest, src);
248
249   dest->trueLabel = copySymbol (src->trueLabel);
250   dest->falseLabel = copySymbol (src->falseLabel);
251   dest->left = copyAst (src->left);
252   dest->right = copyAst (src->right);
253 exit:
254   return dest;
255
256 }
257
258 /*-----------------------------------------------------------------*/
259 /* removeIncDecOps: remove for side effects in *_ASSIGN's          */
260 /*                  "*s++ += 3" -> "*s++ = *s++ + 3"               */
261 /*-----------------------------------------------------------------*/
262 ast *removeIncDecOps (ast * tree) {
263
264   // traverse the tree and remove inc/dec ops
265
266   if (!tree)
267     return NULL;
268
269   if (tree->type == EX_OP &&
270       (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
271     if (tree->left)
272       tree=tree->left;
273     else
274       tree=tree->right;
275   }
276
277   tree->left=removeIncDecOps(tree->left);
278   tree->right=removeIncDecOps(tree->right);
279
280  return tree;
281 }
282
283 /*-----------------------------------------------------------------*/
284 /* removePreIncDecOps: remove for side effects in *_ASSIGN's       */
285 /*                  "*++s += 3" -> "*++s = *++s + 3"               */
286 /*-----------------------------------------------------------------*/
287 ast *removePreIncDecOps (ast * tree) {
288
289   // traverse the tree and remove pre-inc/dec ops
290
291   if (!tree)
292     return NULL;
293
294   if (tree->type == EX_OP &&
295       (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
296     if (tree->right)
297       tree=tree->right;
298   }
299
300   tree->left=removePreIncDecOps(tree->left);
301   tree->right=removePreIncDecOps(tree->right);
302
303  return tree;
304 }
305
306 /*-----------------------------------------------------------------*/
307 /* removePostIncDecOps: remove for side effects in *_ASSIGN's      */
308 /*                  "*s++ += 3" -> "*s++ = *s++ + 3"               */
309 /*-----------------------------------------------------------------*/
310 ast *removePostIncDecOps (ast * tree) {
311
312   // traverse the tree and remove pre-inc/dec ops
313
314   if (!tree)
315     return NULL;
316
317   if (tree->type == EX_OP &&
318       (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
319     if (tree->left)
320       tree=tree->left;
321   }
322
323   tree->left=removePostIncDecOps(tree->left);
324   tree->right=removePostIncDecOps(tree->right);
325
326  return tree;
327 }
328
329 /*-----------------------------------------------------------------*/
330 /* hasSEFcalls - returns TRUE if tree has a function call          */
331 /*-----------------------------------------------------------------*/
332 bool
333 hasSEFcalls (ast * tree)
334 {
335   if (!tree)
336     return FALSE;
337
338   if (tree->type == EX_OP &&
339       (tree->opval.op == CALL ||
340        tree->opval.op == PCALL ||
341        tree->opval.op == '=' ||
342        tree->opval.op == INC_OP ||
343        tree->opval.op == DEC_OP))
344     return TRUE;
345
346   return (hasSEFcalls (tree->left) |
347           hasSEFcalls (tree->right));
348 }
349
350 /*-----------------------------------------------------------------*/
351 /* isAstEqual - compares two asts & returns 1 if they are equal    */
352 /*-----------------------------------------------------------------*/
353 static int
354 isAstEqual (ast * t1, ast * t2)
355 {
356   if (!t1 && !t2)
357     return 1;
358
359   if (!t1 || !t2)
360     return 0;
361
362   /* match type */
363   if (t1->type != t2->type)
364     return 0;
365
366   switch (t1->type)
367     {
368     case EX_OP:
369       if (t1->opval.op != t2->opval.op)
370         return 0;
371       return (isAstEqual (t1->left, t2->left) &&
372               isAstEqual (t1->right, t2->right));
373       break;
374
375     case EX_VALUE:
376       if (t1->opval.val->sym)
377         {
378           if (!t2->opval.val->sym)
379             return 0;
380           else
381             return isSymbolEqual (t1->opval.val->sym,
382                                   t2->opval.val->sym);
383         }
384       else
385         {
386           if (t2->opval.val->sym)
387             return 0;
388           else
389             return (floatFromVal (t1->opval.val) ==
390                     floatFromVal (t2->opval.val));
391         }
392       break;
393
394       /* only compare these two types */
395     default:
396       return 0;
397     }
398
399   return 0;
400 }
401
402 /*-----------------------------------------------------------------*/
403 /* resolveSymbols - resolve symbols from the symbol table          */
404 /*-----------------------------------------------------------------*/
405 ast *
406 resolveSymbols (ast * tree)
407 {
408   /* walk the entire tree and check for values */
409   /* with symbols if we find one then replace  */
410   /* symbol with that from the symbol table    */
411
412   if (tree == NULL)
413     return tree;
414
415 #if 0
416   /* print the line          */
417   /* if not block & function */
418   if (tree->type == EX_OP &&
419       (tree->opval.op != FUNCTION &&
420        tree->opval.op != BLOCK &&
421        tree->opval.op != NULLOP))
422     {
423       filename = tree->filename;
424       lineno = tree->lineno;
425     }
426 #endif
427
428   /* make sure we resolve the true & false labels for ifx */
429   if (tree->type == EX_OP && tree->opval.op == IFX)
430     {
431       symbol *csym;
432
433       if (tree->trueLabel)
434         {
435           if ((csym = findSym (LabelTab, tree->trueLabel,
436                                tree->trueLabel->name)))
437             tree->trueLabel = csym;
438           else
439             werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
440                       tree->trueLabel->name);
441         }
442
443       if (tree->falseLabel)
444         {
445           if ((csym = findSym (LabelTab,
446                                tree->falseLabel,
447                                tree->falseLabel->name)))
448             tree->falseLabel = csym;
449           else
450             werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
451                       tree->falseLabel->name);
452         }
453
454     }
455
456   /* if this is a label resolve it from the labelTab */
457   if (IS_AST_VALUE (tree) &&
458       tree->opval.val->sym &&
459       tree->opval.val->sym->islbl)
460     {
461
462       symbol *csym = findSym (LabelTab, tree->opval.val->sym,
463                               tree->opval.val->sym->name);
464
465       if (!csym)
466         werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
467                   tree->opval.val->sym->name);
468       else
469         tree->opval.val->sym = csym;
470
471       goto resolveChildren;
472     }
473
474   /* do only for leafs */
475   if (IS_AST_VALUE (tree) &&
476       tree->opval.val->sym &&
477       !tree->opval.val->sym->implicit)
478     {
479
480       symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
481
482       /* if found in the symbol table & they r not the same */
483       if (csym && tree->opval.val->sym != csym)
484         {
485           tree->opval.val->sym = csym;
486           tree->opval.val->type = csym->type;
487           tree->opval.val->etype = csym->etype;
488         }
489
490       /* if not found in the symbol table */
491       /* mark it as undefined assume it is */
492       /* an integer in data space         */
493       if (!csym && !tree->opval.val->sym->implicit)
494         {
495
496           /* if this is a function name then */
497           /* mark it as returning an int     */
498           if (tree->funcName)
499             {
500               tree->opval.val->sym->type = newLink (DECLARATOR);
501               DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
502               tree->opval.val->sym->type->next =
503                 tree->opval.val->sym->etype = newIntLink ();
504               tree->opval.val->etype = tree->opval.val->etype;
505               tree->opval.val->type = tree->opval.val->sym->type;
506               werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
507                         tree->opval.val->sym->name);
508               //tree->opval.val->sym->undefined = 1;
509               allocVariables (tree->opval.val->sym);
510             }
511           else
512             {
513               tree->opval.val->sym->undefined = 1;
514               tree->opval.val->type =
515                 tree->opval.val->etype = newIntLink ();
516               tree->opval.val->sym->type =
517                 tree->opval.val->sym->etype = newIntLink ();
518             }
519         }
520     }
521
522 resolveChildren:
523   resolveSymbols (tree->left);
524   resolveSymbols (tree->right);
525
526   return tree;
527 }
528
529 /*-----------------------------------------------------------------*/
530 /* setAstLineno - walks a ast tree & sets the line number          */
531 /*-----------------------------------------------------------------*/
532 int setAstLineno (ast * tree, int lineno)
533 {
534   if (!tree)
535     return 0;
536
537   tree->lineno = lineno;
538   setAstLineno (tree->left, lineno);
539   setAstLineno (tree->right, lineno);
540   return 0;
541 }
542
543 /*-----------------------------------------------------------------*/
544 /* funcOfType :- function of type with name                        */
545 /*-----------------------------------------------------------------*/
546 symbol *
547 funcOfType (char *name, sym_link * type, sym_link * argType,
548             int nArgs, int rent)
549 {
550   symbol *sym;
551   /* create the symbol */
552   sym = newSymbol (name, 0);
553
554   /* setup return value */
555   sym->type = newLink (DECLARATOR);
556   DCL_TYPE (sym->type) = FUNCTION;
557   sym->type->next = copyLinkChain (type);
558   sym->etype = getSpec (sym->type);
559   FUNC_ISREENT(sym->type) = rent ? 1 : 0;
560
561   /* if arguments required */
562   if (nArgs)
563     {
564       value *args;
565       args = FUNC_ARGS(sym->type) = newValue ();
566
567       while (nArgs--)
568         {
569           args->type = copyLinkChain (argType);
570           args->etype = getSpec (args->type);
571           SPEC_EXTR(args->etype)=1;
572           if (!nArgs)
573             break;
574           args = args->next = newValue ();
575         }
576     }
577
578   /* save it */
579   addSymChain (&sym);
580   sym->cdef = 1;
581   allocVariables (sym);
582   return sym;
583
584 }
585
586 /*-----------------------------------------------------------------*/
587 /* funcOfTypeVarg :- function of type with name and argtype        */
588 /*-----------------------------------------------------------------*/
589 symbol *
590 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
591 {
592
593     symbol *sym;
594     int i ;
595     /* create the symbol */
596     sym = newSymbol (name, 0);
597
598     /* setup return value */
599     sym->type = newLink (DECLARATOR);
600     DCL_TYPE (sym->type) = FUNCTION;
601     sym->type->next = typeFromStr(rtype);
602     sym->etype = getSpec (sym->type);
603
604     /* if arguments required */
605     if (nArgs) {
606         value *args;
607         args = FUNC_ARGS(sym->type) = newValue ();
608
609         for ( i = 0 ; i < nArgs ; i++ ) {
610             args->type = typeFromStr(atypes[i]);
611             args->etype = getSpec (args->type);
612             SPEC_EXTR(args->etype)=1;
613             if ((i + 1) == nArgs) break;
614             args = args->next = newValue ();
615         }
616     }
617
618     /* save it */
619     addSymChain (&sym);
620     sym->cdef = 1;
621     allocVariables (sym);
622     return sym;
623
624 }
625
626 /*-----------------------------------------------------------------*/
627 /* reverseParms - will reverse a parameter tree                    */
628 /*-----------------------------------------------------------------*/
629 static void
630 reverseParms (ast * ptree)
631 {
632   ast *ttree;
633   if (!ptree)
634     return;
635
636   /* top down if we find a nonParm tree then quit */
637   if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
638     {
639       /* The various functions expect the parameter tree to be right heavy. */
640       /* Rotate the tree to be left heavy so that after reversal it is */
641       /* right heavy again. */
642       while ((ttree = ptree->right) && ttree->type == EX_OP &&
643              ttree->opval.op == PARAM)
644         {
645           ptree->right = ttree->right;
646           ttree->right = ttree->left;
647           ttree->left = ptree->left;
648           ptree->left = ttree;
649         }
650
651       /* Now reverse */
652       ttree = ptree->left;
653       ptree->left = ptree->right;
654       ptree->right = ttree;
655       ptree->reversed = 1;
656       reverseParms (ptree->left);
657       reverseParms (ptree->right);
658     }
659
660   return;
661 }
662
663 /*-----------------------------------------------------------------*/
664 /* processParms  - makes sure the parameters are okay and do some  */
665 /*                 processing with them                            */
666 /*-----------------------------------------------------------------*/
667 static int
668 processParms (ast *func,
669               value *defParm,
670               ast **actParm,
671               int *parmNumber, /* unused, although updated */
672               bool rightmost)
673 {
674   RESULT_TYPE resultType;
675   sym_link *functype;
676
677   /* if none of them exist */
678   if (!defParm && !*actParm)
679     return 0;
680
681   if (defParm)
682     {
683       if (getenv("DEBUG_SANITY"))
684         {
685           fprintf (stderr, "processParms: %s ", defParm->name);
686         }
687       /* make sure the type is complete and sane */
688       checkTypeSanity(defParm->etype, defParm->name);
689     }
690
691   if (IS_CODEPTR (func->ftype))
692     functype = func->ftype->next;
693   else
694     functype = func->ftype;
695
696   /* if the function is being called via a pointer &   */
697   /* it has not been defined a reentrant then we cannot */
698   /* have parameters                                   */
699   /* PIC16 port can... */
700   if (!TARGET_IS_PIC16)
701     {
702       if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
703         {
704           werror (W_NONRENT_ARGS);
705           fatalError++;
706           return 1;
707         }
708     }
709
710   /* if defined parameters ended but actual parameters */
711   /* exist and this is not defined as a variable arg   */
712   if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
713     {
714       werror (E_TOO_MANY_PARMS);
715       return 1;
716     }
717
718   /* if defined parameters present but no actual parameters */
719   if (defParm && !*actParm)
720     {
721       werror (E_TOO_FEW_PARMS);
722       return 1;
723     }
724
725   /* if this is a PARAM node then match left & right */
726   if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
727     {
728       (*actParm)->decorated = 1;
729       return (processParms (func, defParm,
730                             &(*actParm)->left,  parmNumber, FALSE) ||
731               processParms (func, defParm ? defParm->next : NULL,
732                             &(*actParm)->right, parmNumber, rightmost));
733     }
734   else if (defParm) /* not vararg */
735     {
736       /* If we have found a value node by following only right-hand links,
737        * then we know that there are no more values after us.
738        *
739        * Therefore, if there are more defined parameters, the caller didn't
740        * supply enough.
741        */
742       if (rightmost && defParm->next)
743         {
744           werror (E_TOO_FEW_PARMS);
745           return 1;
746         }
747     }
748
749   /* decorate parameter */
750   resultType = defParm ? getResultTypeFromType (defParm->etype) :
751                          RESULT_TYPE_NONE;
752   *actParm = decorateType (*actParm, resultType);
753
754   if (IS_VOID((*actParm)->ftype))
755     {
756       werror (E_VOID_VALUE_USED);
757       return 1;
758     }
759
760   /* If this is a varargs function... */
761   if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
762     {
763       ast *newType = NULL;
764       sym_link *ftype;
765
766       if (IS_CAST_OP (*actParm)
767           || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
768         {
769           /* Parameter was explicitly typecast; don't touch it. */
770           return 0;
771         }
772
773       ftype = (*actParm)->ftype;
774
775       /* If it's a char, upcast to int. */
776       if (IS_INTEGRAL (ftype)
777           && (getSize (ftype) < (unsigned) INTSIZE))
778         {
779           newType = newAst_LINK(INTTYPE);
780         }
781
782       if (IS_PTR(ftype) && !IS_GENPTR(ftype))
783         {
784           newType = newAst_LINK (copyLinkChain(ftype));
785           DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
786         }
787
788       if (IS_AGGREGATE (ftype))
789         {
790           newType = newAst_LINK (copyLinkChain (ftype));
791           DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
792         }
793
794       if (newType)
795         {
796           /* cast required; change this op to a cast. */
797           (*actParm)->decorated = 0;
798            *actParm = newNode (CAST, newType, *actParm);
799           (*actParm)->lineno = (*actParm)->right->lineno;
800
801           decorateType (*actParm, RESULT_TYPE_NONE);
802         }
803       return 0;
804     } /* vararg */
805
806   /* if defined parameters ended but actual has not & */
807   /* reentrant */
808   if (!defParm && *actParm &&
809       (options.stackAuto || IFFUNC_ISREENT (functype)))
810     return 0;
811
812   resolveSymbols (*actParm);
813
814   /* the parameter type must be at least castable */
815   if (compareType (defParm->type, (*actParm)->ftype) == 0)
816     {
817       werror (E_INCOMPAT_TYPES);
818       printFromToType ((*actParm)->ftype, defParm->type);
819       return 1;
820     }
821
822   /* if the parameter is castable then add the cast */
823   if (compareType (defParm->type, (*actParm)->ftype) < 0)
824     {
825       ast *pTree;
826
827       resultType = getResultTypeFromType (defParm->etype);
828       pTree = resolveSymbols (copyAst (*actParm));
829
830       /* now change the current one to a cast */
831       (*actParm)->type = EX_OP;
832       (*actParm)->opval.op = CAST;
833       (*actParm)->left = newAst_LINK (defParm->type);
834       (*actParm)->right = pTree;
835       (*actParm)->decorated = 0; /* force typechecking */
836       decorateType (*actParm, resultType);
837     }
838
839   /* make a copy and change the regparm type to the defined parm */
840   (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
841   SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
842   SPEC_ARGREG  ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
843   (*parmNumber)++;
844   return 0;
845 }
846
847 /*-----------------------------------------------------------------*/
848 /* createIvalType - generates ival for basic types                 */
849 /*-----------------------------------------------------------------*/
850 static ast *
851 createIvalType (ast * sym, sym_link * type, initList * ilist)
852 {
853   ast *iExpr;
854
855   /* if initList is deep */
856   if (ilist->type == INIT_DEEP)
857     ilist = ilist->init.deep;
858
859   iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
860   return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
861 }
862
863 /*-----------------------------------------------------------------*/
864 /* createIvalStruct - generates initial value for structures       */
865 /*-----------------------------------------------------------------*/
866 static ast *
867 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
868 {
869   ast *rast = NULL;
870   ast *lAst;
871   symbol *sflds;
872   initList *iloop;
873
874   sflds = SPEC_STRUCT (type)->fields;
875   if (ilist->type != INIT_DEEP)
876     {
877       werror (E_INIT_STRUCT, "");
878       return NULL;
879     }
880
881   iloop = ilist->init.deep;
882
883   for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
884     {
885       /* if we have come to end */
886       if (!iloop)
887         break;
888       sflds->implicit = 1;
889       lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
890       lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
891       rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
892                                                        iloop, rast, rootValue)),
893                            RESULT_TYPE_NONE);
894
895     }
896
897   if (iloop) {
898     werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
899               W_EXCESS_INITIALIZERS, "struct",
900               sym->opval.val->sym->name);
901   }
902
903   return rast;
904 }
905
906
907 /*-----------------------------------------------------------------*/
908 /* createIvalArray - generates code for array initialization       */
909 /*-----------------------------------------------------------------*/
910 static ast *
911 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
912 {
913   ast *rast = NULL;
914   initList *iloop;
915   int lcnt = 0, size = 0;
916   literalList *literalL;
917
918   /* take care of the special   case  */
919   /* array of characters can be init  */
920   /* by a string                      */
921   if (IS_CHAR (type->next))
922     if ((rast = createIvalCharPtr (sym,
923                                    type,
924                         decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
925                                    rootValue)))
926
927       return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
928
929   /* not the special case             */
930   if (ilist->type != INIT_DEEP)
931   {
932       werror (E_INIT_STRUCT, "");
933       return NULL;
934   }
935
936   iloop = ilist->init.deep;
937   lcnt = DCL_ELEM (type);
938
939   if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
940   {
941       ast *aSym;
942
943       aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
944
945       rast = newNode(ARRAYINIT, aSym, NULL);
946       rast->values.constlist = literalL;
947
948       // Make sure size is set to length of initializer list.
949       while (iloop)
950       {
951           size++;
952           iloop = iloop->next;
953       }
954
955       if (lcnt && size > lcnt)
956       {
957           // Array size was specified, and we have more initializers than needed.
958           char *name=sym->opval.val->sym->name;
959           int lineno=sym->opval.val->sym->lineDef;
960           char *filename=sym->opval.val->sym->fileDef;
961
962           werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
963       }
964   }
965   else
966   {
967       for (;;)
968       {
969           ast *aSym;
970
971           aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
972           aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
973           rast = createIval (aSym, type->next, iloop, rast, rootValue);
974           iloop = (iloop ? iloop->next : NULL);
975           if (!iloop)
976           {
977               break;
978           }
979
980           /* no of elements given and we    */
981           /* have generated for all of them */
982           if (!--lcnt)
983           {
984               // is this a better way? at least it won't crash
985               char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
986               int lineno = iloop->lineno;
987               char *filename = iloop->filename;
988               werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
989
990               break;
991           }
992       }
993   }
994
995   /* if we have not been given a size  */
996   if (!DCL_ELEM (type))
997     {
998       /* check, if it's a flexible array */
999       if (IS_STRUCT (AST_VALUE (rootValue)->type))
1000         AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1001       else
1002         DCL_ELEM (type) = size;
1003     }
1004
1005   return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1006 }
1007
1008
1009 /*-----------------------------------------------------------------*/
1010 /* createIvalCharPtr - generates initial values for char pointers  */
1011 /*-----------------------------------------------------------------*/
1012 static ast *
1013 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1014 {
1015   ast *rast = NULL;
1016   unsigned size = 0;
1017
1018   /* if this is a pointer & right is a literal array then */
1019   /* just assignment will do                              */
1020   if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1021                          SPEC_SCLS (iexpr->etype) == S_CODE)
1022                         && IS_ARRAY (iexpr->ftype)))
1023     return newNode ('=', sym, iexpr);
1024
1025   /* left side is an array so we have to assign each */
1026   /* element                                         */
1027   if ((IS_LITERAL (iexpr->etype) ||
1028        SPEC_SCLS (iexpr->etype) == S_CODE)
1029       && IS_ARRAY (iexpr->ftype))
1030     {
1031       /* for each character generate an assignment */
1032       /* to the array element */
1033       char *s = SPEC_CVAL (iexpr->etype).v_char;
1034       unsigned int i = 0;
1035       unsigned int symsize = getSize (type);
1036
1037       size = getSize (iexpr->ftype);
1038       if (symsize && size>symsize)
1039         {
1040           if (size>(symsize+1))
1041             {
1042               char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1043
1044               werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1045                         "string", name);
1046             }
1047           size = symsize;
1048         }
1049
1050       for (i=0;i<size;i++)
1051         {
1052           rast = newNode (NULLOP,
1053                           rast,
1054                           newNode ('=',
1055                                    newNode ('[', sym,
1056                                    newAst_VALUE (valueFromLit ((float) i))),
1057                                    newAst_VALUE (valueFromLit (*s))));
1058           s++;
1059         }
1060
1061       // now WE don't need iexpr's symbol anymore
1062       freeStringSymbol(AST_SYMBOL(iexpr));
1063
1064       /* if we have not been given a size  */
1065       if (!DCL_ELEM (type))
1066         {
1067           /* check, if it's a flexible array */
1068           if (IS_STRUCT (AST_VALUE (rootVal)->type))
1069             AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1070           else
1071             DCL_ELEM (type) = size;
1072         }
1073
1074       return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1075     }
1076
1077   return NULL;
1078 }
1079
1080 /*-----------------------------------------------------------------*/
1081 /* createIvalPtr - generates initial value for pointers            */
1082 /*-----------------------------------------------------------------*/
1083 static ast *
1084 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1085 {
1086   ast *rast;
1087   ast *iexpr;
1088
1089   /* if deep then   */
1090   if (ilist->type == INIT_DEEP)
1091     ilist = ilist->init.deep;
1092
1093   iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1094
1095   /* if character pointer */
1096   if (IS_CHAR (type->next))
1097     if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1098       return rast;
1099
1100   return newNode ('=', sym, iexpr);
1101 }
1102
1103 /*-----------------------------------------------------------------*/
1104 /* createIval - generates code for initial value                   */
1105 /*-----------------------------------------------------------------*/
1106 static ast *
1107 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1108 {
1109   ast *rast = NULL;
1110
1111   if (!ilist)
1112     return NULL;
1113
1114   /* if structure then    */
1115   if (IS_STRUCT (type))
1116     rast = createIvalStruct (sym, type, ilist, rootValue);
1117   else
1118     /* if this is a pointer */
1119   if (IS_PTR (type))
1120     rast = createIvalPtr (sym, type, ilist, rootValue);
1121   else
1122     /* if this is an array   */
1123   if (IS_ARRAY (type))
1124     rast = createIvalArray (sym, type, ilist, rootValue);
1125   else
1126     /* if type is SPECIFIER */
1127   if (IS_SPEC (type))
1128     rast = createIvalType (sym, type, ilist);
1129
1130   if (wid)
1131     return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1132   else
1133     return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1134 }
1135
1136 /*-----------------------------------------------------------------*/
1137 /* initAggregates - initialises aggregate variables with initv     */
1138 /*-----------------------------------------------------------------*/
1139 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1140   ast *newAst = newAst_VALUE (symbolVal (sym));
1141   return createIval (newAst, sym->type, ival, wid, newAst);
1142 }
1143
1144 /*-----------------------------------------------------------------*/
1145 /* gatherAutoInit - creates assignment expressions for initial     */
1146 /*    values                 */
1147 /*-----------------------------------------------------------------*/
1148 static ast *
1149 gatherAutoInit (symbol * autoChain)
1150 {
1151   ast *init = NULL;
1152   ast *work;
1153   symbol *sym;
1154
1155   inInitMode = 1;
1156   for (sym = autoChain; sym; sym = sym->next)
1157     {
1158
1159       /* resolve the symbols in the ival */
1160       if (sym->ival)
1161         resolveIvalSym (sym->ival, sym->type);
1162
1163 #if 1
1164       /* if we are PIC16 port,
1165        * and this is a static,
1166        * and have initial value,
1167        * and not S_CODE, don't emit in gs segment,
1168        * but allow glue.c:pic16emitRegularMap to put symbol
1169        * in idata section */
1170       if(TARGET_IS_PIC16 &&
1171         IS_STATIC (sym->etype) && sym->ival
1172         && SPEC_SCLS(sym->etype) != S_CODE) {
1173         SPEC_SCLS (sym->etype) = S_DATA;
1174         continue;
1175       }
1176 #endif
1177
1178       /* if this is a static variable & has an */
1179       /* initial value the code needs to be lifted */
1180       /* here to the main portion since they can be */
1181       /* initialised only once at the start    */
1182       if (IS_STATIC (sym->etype) && sym->ival &&
1183           SPEC_SCLS (sym->etype) != S_CODE)
1184         {
1185           symbol *newSym;
1186
1187           /* insert the symbol into the symbol table */
1188           /* with level = 0 & name = rname       */
1189           newSym = copySymbol (sym);
1190           addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1191
1192           /* now lift the code to main */
1193           if (IS_AGGREGATE (sym->type)) {
1194             work = initAggregates (sym, sym->ival, NULL);
1195           } else {
1196             if (getNelements(sym->type, sym->ival)>1) {
1197               werrorfl (sym->fileDef, sym->lineDef,
1198                         W_EXCESS_INITIALIZERS, "scalar",
1199                         sym->name);
1200             }
1201             work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1202                             list2expr (sym->ival));
1203           }
1204
1205           setAstLineno (work, sym->lineDef);
1206
1207           sym->ival = NULL;
1208           if (staticAutos)
1209             staticAutos = newNode (NULLOP, staticAutos, work);
1210           else
1211             staticAutos = work;
1212
1213           continue;
1214         }
1215
1216       /* if there is an initial value */
1217       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1218         {
1219           initList *ilist=sym->ival;
1220
1221           while (ilist->type == INIT_DEEP) {
1222             ilist = ilist->init.deep;
1223           }
1224
1225           /* update lineno for error msg */
1226           lineno=sym->lineDef;
1227           setAstLineno (ilist->init.node, lineno);
1228
1229           if (IS_AGGREGATE (sym->type)) {
1230             work = initAggregates (sym, sym->ival, NULL);
1231           } else {
1232             if (getNelements(sym->type, sym->ival)>1) {
1233               werrorfl (sym->fileDef, sym->lineDef,
1234                         W_EXCESS_INITIALIZERS, "scalar",
1235                         sym->name);
1236             }
1237             work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1238                             list2expr (sym->ival));
1239           }
1240
1241           // just to be sure
1242           setAstLineno (work, sym->lineDef);
1243
1244           sym->ival = NULL;
1245           if (init)
1246             init = newNode (NULLOP, init, work);
1247           else
1248             init = work;
1249         }
1250     }
1251   inInitMode = 0;
1252   return init;
1253 }
1254
1255 /*-----------------------------------------------------------------*/
1256 /* freeStringSymbol - delete a literal string if no more usage     */
1257 /*-----------------------------------------------------------------*/
1258 void freeStringSymbol(symbol *sym) {
1259   /* make sure this is a literal string */
1260   assert (sym->isstrlit);
1261   if (--sym->isstrlit == 0) { // lower the usage count
1262     memmap *segment=SPEC_OCLS(sym->etype);
1263     if (segment) {
1264       deleteSetItem(&segment->syms, sym);
1265     }
1266   }
1267 }
1268
1269 /*-----------------------------------------------------------------*/
1270 /* stringToSymbol - creates a symbol from a literal string         */
1271 /*-----------------------------------------------------------------*/
1272 static value *
1273 stringToSymbol (value * val)
1274 {
1275   char name[SDCC_NAME_MAX + 1];
1276   static int charLbl = 0;
1277   symbol *sym;
1278   set *sp;
1279   unsigned int size;
1280
1281   // have we heard this before?
1282   for (sp=statsg->syms; sp; sp=sp->next) {
1283     sym=sp->item;
1284     size = getSize (sym->type);
1285     if (sym->isstrlit && size == getSize (val->type) &&
1286         !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1287       // yes, this is old news. Don't publish it again.
1288       sym->isstrlit++; // but raise the usage count
1289       return symbolVal(sym);
1290     }
1291   }
1292
1293   SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1294   sym = newSymbol (name, 0);    /* make it @ level 0 */
1295   strncpyz (sym->rname, name, SDCC_NAME_MAX);
1296
1297   /* copy the type from the value passed */
1298   sym->type = copyLinkChain (val->type);
1299   sym->etype = getSpec (sym->type);
1300   /* change to storage class & output class */
1301   SPEC_SCLS (sym->etype) = S_CODE;
1302   SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1303   SPEC_STAT (sym->etype) = 1;
1304   /* make the level & block = 0 */
1305   sym->block = sym->level = 0;
1306   sym->isstrlit = 1;
1307   /* create an ival */
1308   sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1309   if (noAlloc == 0)
1310     {
1311       /* allocate it */
1312       addSymChain (&sym);
1313       allocVariables (sym);
1314     }
1315   sym->ival = NULL;
1316   return symbolVal (sym);
1317
1318 }
1319
1320 /*-----------------------------------------------------------------*/
1321 /* processBlockVars - will go thru the ast looking for block if    */
1322 /*                    a block is found then will allocate the syms */
1323 /*                    will also gather the auto inits present      */
1324 /*-----------------------------------------------------------------*/
1325 ast *
1326 processBlockVars (ast * tree, int *stack, int action)
1327 {
1328   if (!tree)
1329     return NULL;
1330
1331   /* if this is a block */
1332   if (tree->type == EX_OP && tree->opval.op == BLOCK)
1333     {
1334       ast *autoInit;
1335
1336       if (action == ALLOCATE)
1337         {
1338           *stack += allocVariables (tree->values.sym);
1339           autoInit = gatherAutoInit (tree->values.sym);
1340
1341           /* if there are auto inits then do them */
1342           if (autoInit)
1343             tree->left = newNode (NULLOP, autoInit, tree->left);
1344         }
1345       else                      /* action is deallocate */
1346         deallocLocal (tree->values.sym);
1347     }
1348
1349   processBlockVars (tree->left, stack, action);
1350   processBlockVars (tree->right, stack, action);
1351   return tree;
1352 }
1353
1354
1355 /*-------------------------------------------------------------*/
1356 /* constExprTree - returns TRUE if this tree is a constant     */
1357 /*                 expression                                  */
1358 /*-------------------------------------------------------------*/
1359 bool constExprTree (ast *cexpr) {
1360
1361   if (!cexpr) {
1362     return TRUE;
1363   }
1364
1365   cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1366
1367   switch (cexpr->type)
1368     {
1369     case EX_VALUE:
1370       if (IS_AST_LIT_VALUE(cexpr)) {
1371         // this is a literal
1372         return TRUE;
1373       }
1374       if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1375         // a function's address will never change
1376         return TRUE;
1377       }
1378       if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1379         // an array's address will never change
1380         return TRUE;
1381       }
1382       if (IS_AST_SYM_VALUE(cexpr) &&
1383           IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1384         // a symbol in code space will never change
1385         // This is only for the 'char *s="hallo"' case and will have to leave
1386         //printf(" code space symbol");
1387         return TRUE;
1388       }
1389       return FALSE;
1390     case EX_LINK:
1391       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1392               "unexpected link in expression tree\n");
1393       return FALSE;
1394     case EX_OP:
1395       if (cexpr->opval.op==ARRAYINIT) {
1396         // this is a list of literals
1397         return TRUE;
1398       }
1399       if (cexpr->opval.op=='=') {
1400         return constExprTree(cexpr->right);
1401       }
1402       if (cexpr->opval.op==CAST) {
1403         // cast ignored, maybe we should throw a warning here?
1404         return constExprTree(cexpr->right);
1405       }
1406       if (cexpr->opval.op=='&') {
1407         return TRUE;
1408       }
1409       if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1410         return FALSE;
1411       }
1412       if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1413         return TRUE;
1414       }
1415       return FALSE;
1416     case EX_OPERAND:
1417       return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1418     }
1419   return FALSE;
1420 }
1421
1422 /*-----------------------------------------------------------------*/
1423 /* constExprValue - returns the value of a constant expression     */
1424 /*                  or NULL if it is not a constant expression     */
1425 /*-----------------------------------------------------------------*/
1426 value *
1427 constExprValue (ast * cexpr, int check)
1428 {
1429   cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1430
1431   /* if this is not a constant then */
1432   if (!IS_LITERAL (cexpr->ftype))
1433     {
1434       /* then check if this is a literal array
1435          in code segment */
1436       if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1437           SPEC_CVAL (cexpr->etype).v_char &&
1438           IS_ARRAY (cexpr->ftype))
1439         {
1440           value *val = valFromType (cexpr->ftype);
1441           SPEC_SCLS (val->etype) = S_LITERAL;
1442           val->sym = cexpr->opval.val->sym;
1443           val->sym->type = copyLinkChain (cexpr->ftype);
1444           val->sym->etype = getSpec (val->sym->type);
1445           strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1446           return val;
1447         }
1448
1449       /* if we are casting a literal value then */
1450       if (IS_AST_OP (cexpr) &&
1451           cexpr->opval.op == CAST &&
1452           IS_LITERAL (cexpr->right->ftype))
1453         {
1454         return valCastLiteral (cexpr->ftype,
1455                                floatFromVal (cexpr->right->opval.val));
1456         }
1457
1458       if (IS_AST_VALUE (cexpr))
1459         {
1460         return cexpr->opval.val;
1461         }
1462
1463       if (check)
1464         werror (E_CONST_EXPECTED, "found expression");
1465
1466       return NULL;
1467     }
1468
1469   /* return the value */
1470   if (IS_AST_VALUE (cexpr))
1471     {
1472       return cexpr->opval.val;
1473     }
1474    return NULL;
1475 }
1476
1477 /*-----------------------------------------------------------------*/
1478 /* isLabelInAst - will return true if a given label is found       */
1479 /*-----------------------------------------------------------------*/
1480 bool
1481 isLabelInAst (symbol * label, ast * tree)
1482 {
1483   if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1484     return FALSE;
1485
1486   if (IS_AST_OP (tree) &&
1487       tree->opval.op == LABEL &&
1488       isSymbolEqual (AST_SYMBOL (tree->left), label))
1489     return TRUE;
1490
1491   return isLabelInAst (label, tree->right) &&
1492     isLabelInAst (label, tree->left);
1493
1494 }
1495
1496 /*-----------------------------------------------------------------*/
1497 /* isLoopCountable - return true if the loop count can be determi- */
1498 /* -ned at compile time .                                          */
1499 /*-----------------------------------------------------------------*/
1500 bool
1501 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1502                  symbol ** sym, ast ** init, ast ** end)
1503 {
1504
1505   /* the loop is considered countable if the following
1506      conditions are true :-
1507
1508      a) initExpr :- <sym> = <const>
1509      b) condExpr :- <sym> < <const1>
1510      c) loopExpr :- <sym> ++
1511    */
1512
1513   /* first check the initExpr */
1514   if (IS_AST_OP (initExpr) &&
1515       initExpr->opval.op == '=' &&      /* is assignment */
1516       IS_AST_SYM_VALUE (initExpr->left))
1517     {                           /* left is a symbol */
1518
1519       *sym = AST_SYMBOL (initExpr->left);
1520       *init = initExpr->right;
1521     }
1522   else
1523     return FALSE;
1524
1525   /* for now the symbol has to be of
1526      integral type */
1527   if (!IS_INTEGRAL ((*sym)->type))
1528     return FALSE;
1529
1530   /* now check condExpr */
1531   if (IS_AST_OP (condExpr))
1532     {
1533
1534       switch (condExpr->opval.op)
1535         {
1536         case '<':
1537           if (IS_AST_SYM_VALUE (condExpr->left) &&
1538               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1539               IS_AST_LIT_VALUE (condExpr->right))
1540             {
1541               *end = condExpr->right;
1542               break;
1543             }
1544           return FALSE;
1545
1546         case '!':
1547           if (IS_AST_OP (condExpr->left) &&
1548               condExpr->left->opval.op == '>' &&
1549               IS_AST_LIT_VALUE (condExpr->left->right) &&
1550               IS_AST_SYM_VALUE (condExpr->left->left) &&
1551               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1552             {
1553
1554               *end = newNode ('+', condExpr->left->right,
1555                               newAst_VALUE (constVal ("1")));
1556               break;
1557             }
1558           return FALSE;
1559
1560         default:
1561           return FALSE;
1562         }
1563
1564     }
1565   else
1566     return FALSE;
1567
1568   /* check loop expression is of the form <sym>++ */
1569   if (!IS_AST_OP (loopExpr))
1570     return FALSE;
1571
1572   /* check if <sym> ++ */
1573   if (loopExpr->opval.op == INC_OP)
1574     {
1575
1576       if (loopExpr->left)
1577         {
1578           /* pre */
1579           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1580               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1581             return TRUE;
1582
1583         }
1584       else
1585         {
1586           /* post */
1587           if (IS_AST_SYM_VALUE (loopExpr->right) &&
1588               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1589             return TRUE;
1590         }
1591
1592     }
1593   else
1594     {
1595       /* check for += */
1596       if (loopExpr->opval.op == ADD_ASSIGN)
1597         {
1598
1599           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1600               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1601               IS_AST_LIT_VALUE (loopExpr->right) &&
1602               (int) AST_LIT_VALUE (loopExpr->right) != 1)
1603             return TRUE;
1604         }
1605     }
1606
1607   return FALSE;
1608 }
1609
1610 /*-----------------------------------------------------------------*/
1611 /* astHasVolatile - returns true if ast contains any volatile      */
1612 /*-----------------------------------------------------------------*/
1613 bool
1614 astHasVolatile (ast * tree)
1615 {
1616   if (!tree)
1617     return FALSE;
1618
1619   if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1620     return TRUE;
1621
1622   if (IS_AST_OP (tree))
1623     return astHasVolatile (tree->left) ||
1624       astHasVolatile (tree->right);
1625   else
1626     return FALSE;
1627 }
1628
1629 /*-----------------------------------------------------------------*/
1630 /* astHasPointer - return true if the ast contains any ptr variable */
1631 /*-----------------------------------------------------------------*/
1632 bool
1633 astHasPointer (ast * tree)
1634 {
1635   if (!tree)
1636     return FALSE;
1637
1638   if (IS_AST_LINK (tree))
1639     return TRUE;
1640
1641   /* if we hit an array expression then check
1642      only the left side */
1643   if (IS_AST_OP (tree) && tree->opval.op == '[')
1644     return astHasPointer (tree->left);
1645
1646   if (IS_AST_VALUE (tree))
1647     return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1648
1649   return astHasPointer (tree->left) ||
1650     astHasPointer (tree->right);
1651
1652 }
1653
1654 /*-----------------------------------------------------------------*/
1655 /* astHasSymbol - return true if the ast has the given symbol      */
1656 /*-----------------------------------------------------------------*/
1657 bool
1658 astHasSymbol (ast * tree, symbol * sym)
1659 {
1660   if (!tree || IS_AST_LINK (tree))
1661     return FALSE;
1662
1663   if (IS_AST_VALUE (tree))
1664     {
1665       if (IS_AST_SYM_VALUE (tree))
1666         return isSymbolEqual (AST_SYMBOL (tree), sym);
1667       else
1668         return FALSE;
1669     }
1670
1671   return astHasSymbol (tree->left, sym) ||
1672     astHasSymbol (tree->right, sym);
1673 }
1674
1675 /*-----------------------------------------------------------------*/
1676 /* astHasDeref - return true if the ast has an indirect access     */
1677 /*-----------------------------------------------------------------*/
1678 static bool
1679 astHasDeref (ast * tree)
1680 {
1681   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1682     return FALSE;
1683
1684   if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1685
1686   return astHasDeref (tree->left) || astHasDeref (tree->right);
1687 }
1688
1689 /*-----------------------------------------------------------------*/
1690 /* isConformingBody - the loop body has to conform to a set of rules */
1691 /* for the loop to be considered reversible read on for rules      */
1692 /*-----------------------------------------------------------------*/
1693 bool
1694 isConformingBody (ast * pbody, symbol * sym, ast * body)
1695 {
1696
1697   /* we are going to do a pre-order traversal of the
1698      tree && check for the following conditions. (essentially
1699      a set of very shallow tests )
1700      a) the sym passed does not participate in
1701      any arithmetic operation
1702      b) There are no function calls
1703      c) all jumps are within the body
1704      d) address of loop control variable not taken
1705      e) if an assignment has a pointer on the
1706      left hand side make sure right does not have
1707      loop control variable */
1708
1709   /* if we reach the end or a leaf then true */
1710   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1711     return TRUE;
1712
1713   /* if anything else is "volatile" */
1714   if (IS_VOLATILE (TETYPE (pbody)))
1715     return FALSE;
1716
1717   /* we will walk the body in a pre-order traversal for
1718      efficiency sake */
1719   switch (pbody->opval.op)
1720     {
1721 /*------------------------------------------------------------------*/
1722     case '[':
1723       // if the loopvar is used as an index
1724       /* array op is commutative -- must check both left & right */
1725       if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1726         return FALSE;
1727       }
1728       return isConformingBody (pbody->right, sym, body)
1729               && isConformingBody (pbody->left, sym, body);
1730
1731 /*------------------------------------------------------------------*/
1732     case PTR_OP:
1733     case '.':
1734       return TRUE;
1735
1736 /*------------------------------------------------------------------*/
1737     case INC_OP:
1738     case DEC_OP:
1739
1740       /* sure we are not sym is not modified */
1741       if (pbody->left &&
1742           IS_AST_SYM_VALUE (pbody->left) &&
1743           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1744         return FALSE;
1745
1746       if (pbody->right &&
1747           IS_AST_SYM_VALUE (pbody->right) &&
1748           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1749         return FALSE;
1750
1751       return TRUE;
1752
1753 /*------------------------------------------------------------------*/
1754
1755     case '*':                   /* can be unary  : if right is null then unary operation */
1756     case '+':
1757     case '-':
1758     case '&':
1759
1760       /* if right is NULL then unary operation  */
1761 /*------------------------------------------------------------------*/
1762 /*----------------------------*/
1763       /*  address of                */
1764 /*----------------------------*/
1765       if (!pbody->right)
1766         {
1767           if (IS_AST_SYM_VALUE (pbody->left) &&
1768               isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1769             return FALSE;
1770           else
1771             return isConformingBody (pbody->left, sym, body);
1772         }
1773       else
1774         {
1775           if (astHasSymbol (pbody->left, sym) ||
1776               astHasSymbol (pbody->right, sym))
1777             return FALSE;
1778         }
1779
1780
1781 /*------------------------------------------------------------------*/
1782     case '|':
1783     case '^':
1784     case '/':
1785     case '%':
1786     case LEFT_OP:
1787     case RIGHT_OP:
1788     case GETABIT:
1789     case GETBYTE:
1790     case GETWORD:
1791
1792       if (IS_AST_SYM_VALUE (pbody->left) &&
1793           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1794         return FALSE;
1795
1796       if (IS_AST_SYM_VALUE (pbody->right) &&
1797           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1798         return FALSE;
1799
1800       return isConformingBody (pbody->left, sym, body) &&
1801         isConformingBody (pbody->right, sym, body);
1802
1803     case '~':
1804     case '!':
1805     case RRC:
1806     case RLC:
1807     case GETHBIT:
1808     case SWAP:
1809       if (IS_AST_SYM_VALUE (pbody->left) &&
1810           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1811         return FALSE;
1812       return isConformingBody (pbody->left, sym, body);
1813
1814 /*------------------------------------------------------------------*/
1815
1816     case AND_OP:
1817     case OR_OP:
1818     case '>':
1819     case '<':
1820     case LE_OP:
1821     case GE_OP:
1822     case EQ_OP:
1823     case NE_OP:
1824     case '?':
1825     case ':':
1826     case SIZEOF:                /* evaluate wihout code generation */
1827
1828       if (IS_AST_SYM_VALUE (pbody->left) &&
1829           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1830         return FALSE;
1831
1832       if (IS_AST_SYM_VALUE (pbody->right) &&
1833           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1834         return FALSE;
1835
1836       return isConformingBody (pbody->left, sym, body) &&
1837         isConformingBody (pbody->right, sym, body);
1838
1839 /*------------------------------------------------------------------*/
1840     case '=':
1841
1842       /* if left has a pointer & right has loop
1843          control variable then we cannot */
1844       if (astHasPointer (pbody->left) &&
1845           astHasSymbol (pbody->right, sym))
1846         return FALSE;
1847       if (astHasVolatile (pbody->left))
1848         return FALSE;
1849
1850       if (IS_AST_SYM_VALUE (pbody->left)) {
1851         // if the loopvar has an assignment
1852         if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1853           return FALSE;
1854         // if the loopvar is used in another (maybe conditional) block
1855         if (astHasSymbol (pbody->right, sym) &&
1856             (pbody->level >= body->level)) {
1857           return FALSE;
1858         }
1859       }
1860
1861       if (astHasVolatile (pbody->left))
1862         return FALSE;
1863
1864       if (astHasDeref(pbody->right)) return FALSE;
1865
1866       return isConformingBody (pbody->left, sym, body) &&
1867         isConformingBody (pbody->right, sym, body);
1868
1869     case MUL_ASSIGN:
1870     case DIV_ASSIGN:
1871     case AND_ASSIGN:
1872     case OR_ASSIGN:
1873     case XOR_ASSIGN:
1874     case RIGHT_ASSIGN:
1875     case LEFT_ASSIGN:
1876     case SUB_ASSIGN:
1877     case ADD_ASSIGN:
1878       assert ("Parser should not have generated this\n");
1879
1880 /*------------------------------------------------------------------*/
1881 /*----------------------------*/
1882       /*      comma operator        */
1883 /*----------------------------*/
1884     case ',':
1885       return isConformingBody (pbody->left, sym, body) &&
1886         isConformingBody (pbody->right, sym, body);
1887
1888 /*------------------------------------------------------------------*/
1889 /*----------------------------*/
1890       /*       function call        */
1891 /*----------------------------*/
1892     case CALL:
1893         /* if local & not passed as paramater then ok */
1894         if (sym->level && !astHasSymbol(pbody->right,sym))
1895             return TRUE;
1896       return FALSE;
1897
1898 /*------------------------------------------------------------------*/
1899 /*----------------------------*/
1900       /*     return statement       */
1901 /*----------------------------*/
1902     case RETURN:
1903       return FALSE;
1904
1905     case GOTO:
1906       if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1907         return TRUE;
1908       else
1909         return FALSE;
1910     case SWITCH:
1911       if (astHasSymbol (pbody->left, sym))
1912         return FALSE;
1913
1914     default:
1915       break;
1916     }
1917
1918   return isConformingBody (pbody->left, sym, body) &&
1919     isConformingBody (pbody->right, sym, body);
1920
1921
1922
1923 }
1924
1925 /*-----------------------------------------------------------------*/
1926 /* isLoopReversible - takes a for loop as input && returns true    */
1927 /* if the for loop is reversible. If yes will set the value of     */
1928 /* the loop control var & init value & termination value           */
1929 /*-----------------------------------------------------------------*/
1930 bool
1931 isLoopReversible (ast * loop, symbol ** loopCntrl,
1932                   ast ** init, ast ** end)
1933 {
1934   /* if option says don't do it then don't */
1935   if (optimize.noLoopReverse)
1936     return 0;
1937   /* there are several tests to determine this */
1938
1939   /* for loop has to be of the form
1940      for ( <sym> = <const1> ;
1941      [<sym> < <const2>]  ;
1942      [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1943      forBody */
1944   if (!isLoopCountable (AST_FOR (loop, initExpr),
1945                         AST_FOR (loop, condExpr),
1946                         AST_FOR (loop, loopExpr),
1947                         loopCntrl, init, end))
1948     return 0;
1949
1950   /* now do some serious checking on the body of the loop
1951    */
1952
1953   return isConformingBody (loop->left, *loopCntrl, loop->left);
1954
1955 }
1956
1957 /*-----------------------------------------------------------------*/
1958 /* replLoopSym - replace the loop sym by loop sym -1               */
1959 /*-----------------------------------------------------------------*/
1960 static void
1961 replLoopSym (ast * body, symbol * sym)
1962 {
1963   /* reached end */
1964   if (!body || IS_AST_LINK (body))
1965     return;
1966
1967   if (IS_AST_SYM_VALUE (body))
1968     {
1969
1970       if (isSymbolEqual (AST_SYMBOL (body), sym))
1971         {
1972
1973           body->type = EX_OP;
1974           body->opval.op = '-';
1975           body->left = newAst_VALUE (symbolVal (sym));
1976           body->right = newAst_VALUE (constVal ("1"));
1977
1978         }
1979
1980       return;
1981
1982     }
1983
1984   replLoopSym (body->left, sym);
1985   replLoopSym (body->right, sym);
1986
1987 }
1988
1989 /*-----------------------------------------------------------------*/
1990 /* reverseLoop - do the actual loop reversal                       */
1991 /*-----------------------------------------------------------------*/
1992 ast *
1993 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1994 {
1995   ast *rloop;
1996
1997   /* create the following tree
1998      <sym> = loopCount ;
1999      for_continue:
2000      forbody
2001      <sym> -= 1;
2002      if (sym) goto for_continue ;
2003      <sym> = end */
2004
2005   /* put it together piece by piece */
2006   rloop = newNode (NULLOP,
2007                    createIf (newAst_VALUE (symbolVal (sym)),
2008                              newNode (GOTO,
2009                                       newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2010                                       NULL), NULL),
2011                    newNode ('=',
2012                             newAst_VALUE (symbolVal (sym)),
2013                             end));
2014
2015   replLoopSym (loop->left, sym);
2016   setAstLineno (rloop, init->lineno);
2017
2018   rloop = newNode (NULLOP,
2019                    newNode ('=',
2020                             newAst_VALUE (symbolVal (sym)),
2021                             newNode ('-', end, init)),
2022                    createLabel (AST_FOR (loop, continueLabel),
2023                                 newNode (NULLOP,
2024                                          loop->left,
2025                                          newNode (NULLOP,
2026                                                   newNode (SUB_ASSIGN,
2027                                                            newAst_VALUE (symbolVal (sym)),
2028                                                            newAst_VALUE (constVal ("1"))),
2029                                                   rloop))));
2030
2031   rloop->lineno=init->lineno;
2032   return decorateType (rloop, RESULT_TYPE_NONE);
2033
2034 }
2035
2036 /*-----------------------------------------------------------------*/
2037 /* searchLitOp - search tree (*ops only) for an ast with literal */
2038 /*-----------------------------------------------------------------*/
2039 static ast *
2040 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2041 {
2042   ast *ret;
2043
2044   if (tree && optimize.global_cse)
2045     {
2046       /* is there a literal operand? */
2047       if (tree->right &&
2048           IS_AST_OP(tree->right) &&
2049           tree->right->right &&
2050           (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2051         {
2052           if (IS_LITERAL (RTYPE (tree->right)) !=
2053               IS_LITERAL (LTYPE (tree->right)))
2054             {
2055               tree->right->decorated = 0;
2056               tree->decorated = 0;
2057               *parent = tree;
2058               return tree->right;
2059             }
2060           ret = searchLitOp (tree->right, parent, ops);
2061           if (ret)
2062             return ret;
2063         }
2064       if (tree->left &&
2065           IS_AST_OP(tree->left) &&
2066           tree->left->right &&
2067           (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2068         {
2069           if (IS_LITERAL (RTYPE (tree->left)) !=
2070               IS_LITERAL (LTYPE (tree->left)))
2071             {
2072               tree->left->decorated = 0;
2073               tree->decorated = 0;
2074               *parent = tree;
2075               return tree->left;
2076             }
2077           ret = searchLitOp (tree->left, parent, ops);
2078           if (ret)
2079             return ret;
2080         }
2081     }
2082   return NULL;
2083 }
2084
2085 /*-----------------------------------------------------------------*/
2086 /* getResultFromType                                               */
2087 /*-----------------------------------------------------------------*/
2088 RESULT_TYPE
2089 getResultTypeFromType (sym_link *type)
2090 {
2091   /* type = getSpec (type); */
2092   if (IS_BIT (type))
2093     return RESULT_TYPE_BIT;
2094   if (IS_BITFIELD (type))
2095     {
2096       int blen = SPEC_BLEN (type);
2097
2098       if (blen <= 1)
2099         return RESULT_TYPE_BIT;
2100       if (blen <= 8)
2101         return RESULT_TYPE_CHAR;
2102       return RESULT_TYPE_INT;
2103     }
2104   if (IS_CHAR (type))
2105     return RESULT_TYPE_CHAR;
2106   if (   IS_INT (type)
2107       && !IS_LONG (type))
2108     return RESULT_TYPE_INT;
2109   return RESULT_TYPE_OTHER;
2110 }
2111
2112 /*-----------------------------------------------------------------*/
2113 /* addCast - adds casts to a type specified by RESULT_TYPE         */
2114 /*-----------------------------------------------------------------*/
2115 static ast *
2116 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2117 {
2118   sym_link *newLink;
2119   bool upCasted = FALSE;
2120
2121   switch (resultType)
2122     {
2123       case RESULT_TYPE_NONE:
2124         /* if thing smaller than int must be promoted to int */
2125         if (!promote ||
2126             getSize (tree->etype) >= INTSIZE)
2127           /* promotion not necessary or already an int */
2128           return tree;
2129         /* char and bits: promote to int */
2130         newLink = newIntLink();
2131         upCasted = TRUE;
2132         break;
2133       case RESULT_TYPE_BIT:
2134         if (!promote ||
2135             /* already an int */
2136             bitsForType (tree->etype) >= 16 ||
2137             /* bit to bit operation: don't promote, the code generators
2138                hopefully know everything about promotion rules */
2139             bitsForType (tree->etype) == 1)
2140           return tree;
2141         newLink = newIntLink();
2142         upCasted = TRUE;
2143         break;
2144       case RESULT_TYPE_CHAR:
2145         if (IS_CHAR (tree->etype) ||
2146             IS_FLOAT(tree->etype) ||
2147             IS_FIXED(tree->etype))
2148           return tree;
2149         newLink = newCharLink();
2150         break;
2151       case RESULT_TYPE_INT:
2152 #if 0
2153         if (getSize (tree->etype) > INTSIZE)
2154           {
2155             /* warn ("Loosing significant digits"); */
2156             return;
2157           }
2158 #endif
2159         /* char: promote to int */
2160         if (!promote ||
2161             getSize (tree->etype) >= INTSIZE)
2162           return tree;
2163         newLink = newIntLink();
2164         upCasted = TRUE;
2165         break;
2166       case RESULT_TYPE_OTHER:
2167         if (!promote)
2168           return tree;
2169         /* return type is long, float: promote char to int */
2170         if (getSize (tree->etype) >= INTSIZE)
2171           return tree;
2172         newLink = newIntLink();
2173         upCasted = TRUE;
2174         break;
2175       default:
2176         return tree;
2177     }
2178   tree->decorated = 0;
2179   tree = newNode (CAST, newAst_LINK (newLink), tree);
2180   tree->lineno = tree->right->lineno;
2181   /* keep unsigned type during cast to smaller type,
2182      but not when promoting from char to int */
2183   if (!upCasted)
2184     SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2185   return decorateType (tree, resultType);
2186 }
2187
2188 /*-----------------------------------------------------------------*/
2189 /* resultTypePropagate - decides if resultType can be propagated   */
2190 /*-----------------------------------------------------------------*/
2191 static RESULT_TYPE
2192 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2193 {
2194   switch (tree->opval.op)
2195     {
2196       case AND_OP:
2197       case OR_OP:
2198         return resultType;
2199       case '=':
2200       case '?':
2201       case ':':
2202       case '|':
2203       case '^':
2204       case '~':
2205       case '*':
2206       case '+':
2207       case '-':
2208       case LABEL:
2209         return resultType;
2210       case '&':
2211         if (!tree->right)
2212           /* can be unary */
2213           return RESULT_TYPE_NONE;
2214         else
2215           return resultType;
2216       case IFX:
2217         return RESULT_TYPE_IFX;
2218       default:
2219         return RESULT_TYPE_NONE;
2220     }
2221 }
2222
2223 /*-----------------------------------------------------------------*/
2224 /* getLeftResultType - gets type from left branch for propagation  */
2225 /*-----------------------------------------------------------------*/
2226 static RESULT_TYPE
2227 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2228 {
2229   switch (tree->opval.op)
2230     {
2231       case '=':
2232       case CAST:
2233         if (IS_PTR (LTYPE (tree)))
2234           return RESULT_TYPE_NONE;
2235         else
2236           return getResultTypeFromType (LETYPE (tree));
2237       case RETURN:
2238         if (IS_PTR (currFunc->type->next))
2239           return RESULT_TYPE_NONE;
2240         else
2241           return getResultTypeFromType (currFunc->type->next);
2242       case '[':
2243         if (!IS_ARRAY (LTYPE (tree)))
2244           return resultType;
2245         if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2246           return RESULT_TYPE_CHAR;
2247         return resultType;
2248       default:
2249         return resultType;
2250     }
2251 }
2252
2253 /*--------------------------------------------------------------------*/
2254 /* decorateType - compute type for this tree, also does type checking.*/
2255 /* This is done bottom up, since type has to flow upwards.            */
2256 /* resultType flows top-down and forces e.g. char-arithmetic, if the  */
2257 /* result is a char and the operand(s) are int's.                     */
2258 /* It also does constant folding, and parameter checking.             */
2259 /*--------------------------------------------------------------------*/
2260 ast *
2261 decorateType (ast * tree, RESULT_TYPE resultType)
2262 {
2263   int parmNumber;
2264   sym_link *p;
2265   RESULT_TYPE resultTypeProp;
2266
2267   if (!tree)
2268     return tree;
2269
2270   /* if already has type then do nothing */
2271   if (tree->decorated)
2272     return tree;
2273
2274   tree->decorated = 1;
2275
2276 #if 0
2277   /* print the line          */
2278   /* if not block & function */
2279   if (tree->type == EX_OP &&
2280       (tree->opval.op != FUNCTION &&
2281        tree->opval.op != BLOCK &&
2282        tree->opval.op != NULLOP))
2283     {
2284       filename = tree->filename;
2285       lineno = tree->lineno;
2286     }
2287 #endif
2288
2289   /* if any child is an error | this one is an error do nothing */
2290   if (tree->isError ||
2291       (tree->left && tree->left->isError) ||
2292       (tree->right && tree->right->isError))
2293     return tree;
2294
2295 /*------------------------------------------------------------------*/
2296 /*----------------------------*/
2297 /*   leaf has been reached    */
2298 /*----------------------------*/
2299   lineno=tree->lineno;
2300   /* if this is of type value */
2301   /* just get the type        */
2302   if (tree->type == EX_VALUE)
2303     {
2304
2305       if (IS_LITERAL (tree->opval.val->etype))
2306         {
2307
2308           /* if this is a character array then declare it */
2309           if (IS_ARRAY (tree->opval.val->type))
2310             tree->opval.val = stringToSymbol (tree->opval.val);
2311
2312           /* otherwise just copy the type information */
2313           COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2314           return tree;
2315         }
2316
2317       if (tree->opval.val->sym)
2318         {
2319           /* if the undefined flag is set then give error message */
2320           if (tree->opval.val->sym->undefined)
2321             {
2322               werror (E_ID_UNDEF, tree->opval.val->sym->name);
2323               /* assume int */
2324               TTYPE (tree) = TETYPE (tree) =
2325                 tree->opval.val->type = tree->opval.val->sym->type =
2326                 tree->opval.val->etype = tree->opval.val->sym->etype =
2327                 copyLinkChain (INTTYPE);
2328             }
2329           else
2330             {
2331
2332               /* if impilicit i.e. struct/union member then no type */
2333               if (tree->opval.val->sym->implicit)
2334                 TTYPE (tree) = TETYPE (tree) = NULL;
2335
2336               else
2337                 {
2338
2339                   /* else copy the type */
2340                   COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2341
2342                   /* and mark it as referenced */
2343                   tree->opval.val->sym->isref = 1;
2344                 }
2345             }
2346         }
2347
2348       return tree;
2349     }
2350
2351   /* if type link for the case of cast */
2352   if (tree->type == EX_LINK)
2353     {
2354       COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2355       return tree;
2356     }
2357
2358   {
2359     ast *dtl, *dtr;
2360
2361     #if 0
2362     if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2363       {
2364         if (tree->left && tree->left->type == EX_OPERAND
2365             && (tree->left->opval.op == INC_OP
2366                 || tree->left->opval.op == DEC_OP)
2367             && tree->left->left)
2368           {
2369             tree->left->right = tree->left->left;
2370             tree->left->left = NULL;
2371           }
2372         if (tree->right && tree->right->type == EX_OPERAND
2373             && (tree->right->opval.op == INC_OP
2374                 || tree->right->opval.op == DEC_OP)
2375             && tree->right->left)
2376           {
2377             tree->right->right = tree->right->left;
2378             tree->right->left = NULL;
2379           }
2380       }
2381     #endif
2382
2383     /* Before decorating the left branch we've to decide in dependence
2384        upon tree->opval.op, if resultType can be propagated */
2385     resultTypeProp = resultTypePropagate (tree, resultType);
2386
2387     if (tree->opval.op == '?')
2388       dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2389     else
2390       dtl = decorateType (tree->left, resultTypeProp);
2391
2392     /* if an array node, we may need to swap branches */
2393     if (tree->opval.op == '[')
2394       {
2395         /* determine which is the array & which the index */
2396         if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2397             IS_INTEGRAL (LTYPE (tree)))
2398           {
2399             ast *tempTree = tree->left;
2400             tree->left = tree->right;
2401             tree->right = tempTree;
2402           }
2403       }
2404
2405     /* After decorating the left branch there's type information available
2406        in tree->left->?type. If the op is e.g. '=' we extract the type
2407        information from there and propagate it to the right branch. */
2408     resultTypeProp = getLeftResultType (tree, resultTypeProp);
2409
2410     switch (tree->opval.op)
2411       {
2412         case '?':
2413           /* delay right side for '?' operator since conditional macro
2414              expansions might rely on this */
2415           dtr = tree->right;
2416           break;
2417         case CALL:
2418           /* decorate right side for CALL (parameter list) in processParms();
2419              there is resultType available */
2420           dtr = tree->right;
2421           break;
2422         default:
2423           dtr = decorateType (tree->right, resultTypeProp);
2424           break;
2425       }
2426
2427     /* this is to take care of situations
2428        when the tree gets rewritten */
2429     if (dtl != tree->left)
2430       tree->left = dtl;
2431     if (dtr != tree->right)
2432       tree->right = dtr;
2433     if ((dtl && dtl->isError) || (dtr && dtr->isError))
2434       return tree;
2435   }
2436
2437   /* depending on type of operator do */
2438
2439   switch (tree->opval.op)
2440     {
2441         /*------------------------------------------------------------------*/
2442         /*----------------------------*/
2443         /*        array node          */
2444         /*----------------------------*/
2445     case '[':
2446
2447       /* first check if this is a array or a pointer */
2448       if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2449         {
2450           werror (E_NEED_ARRAY_PTR, "[]");
2451           goto errorTreeReturn;
2452         }
2453
2454       /* check if the type of the idx */
2455       if (!IS_INTEGRAL (RTYPE (tree)))
2456         {
2457           werror (E_IDX_NOT_INT);
2458           goto errorTreeReturn;
2459         }
2460
2461       /* if the left is an rvalue then error */
2462       if (LRVAL (tree))
2463         {
2464           werror (E_LVALUE_REQUIRED, "array access");
2465           goto errorTreeReturn;
2466         }
2467
2468       if (IS_LITERAL (RTYPE (tree)))
2469         {
2470           int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2471           int arraySize = DCL_ELEM (LTYPE (tree));
2472           if (arraySize && arrayIndex >= arraySize)
2473             {
2474               werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2475             }
2476         }
2477
2478       RRVAL (tree) = 1;
2479       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2480       SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2481       return tree;
2482
2483       /*------------------------------------------------------------------*/
2484       /*----------------------------*/
2485       /*      struct/union          */
2486       /*----------------------------*/
2487     case '.':
2488       /* if this is not a structure */
2489       if (!IS_STRUCT (LTYPE (tree)))
2490         {
2491           werror (E_STRUCT_UNION, ".");
2492           goto errorTreeReturn;
2493         }
2494       TTYPE (tree) = structElemType (LTYPE (tree),
2495                                      (tree->right->type == EX_VALUE ?
2496                                tree->right->opval.val : NULL));
2497       TETYPE (tree) = getSpec (TTYPE (tree));
2498       return tree;
2499
2500       /*------------------------------------------------------------------*/
2501       /*----------------------------*/
2502       /*    struct/union pointer    */
2503       /*----------------------------*/
2504     case PTR_OP:
2505       /* if not pointer to a structure */
2506       if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2507         {
2508           werror (E_PTR_REQD);
2509           goto errorTreeReturn;
2510         }
2511
2512       if (!IS_STRUCT (LTYPE (tree)->next))
2513         {
2514           werror (E_STRUCT_UNION, "->");
2515           goto errorTreeReturn;
2516         }
2517
2518       TTYPE (tree) = structElemType (LTYPE (tree)->next,
2519                                      (tree->right->type == EX_VALUE ?
2520                                tree->right->opval.val : NULL));
2521       TETYPE (tree) = getSpec (TTYPE (tree));
2522
2523       /* adjust the storage class */
2524       switch (DCL_TYPE(tree->left->ftype)) {
2525       case POINTER:
2526         SPEC_SCLS(TETYPE(tree)) = S_DATA;
2527         break;
2528       case FPOINTER:
2529         SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2530         break;
2531       case CPOINTER:
2532         SPEC_SCLS(TETYPE(tree)) = S_CODE;
2533         break;
2534       case GPOINTER:
2535         SPEC_SCLS (TETYPE (tree)) = 0;
2536         break;
2537       case PPOINTER:
2538         SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2539         break;
2540       case IPOINTER:
2541         SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2542         break;
2543       case EEPPOINTER:
2544         SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2545         break;
2546       case UPOINTER:
2547         SPEC_SCLS (TETYPE (tree)) = 0;
2548         break;
2549       case ARRAY:
2550       case FUNCTION:
2551         break;
2552       }
2553
2554       /* This breaks with extern declarations, bitfields, and perhaps other */
2555       /* cases (gcse). Let's leave this optimization disabled for now and   */
2556       /* ponder if there's a safe way to do this. -- EEP                    */
2557       #if 0
2558       if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2559           && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2560         {
2561             /* If defined    struct type at addr var
2562                then rewrite  (&struct var)->member
2563                as            temp
2564                and define    membertype at (addr+offsetof(struct var,member)) temp
2565             */
2566             symbol *sym;
2567             symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2568                                                 AST_SYMBOL(tree->right));
2569
2570             sym = newSymbol(genSymName (0), 0);
2571             sym->type = TTYPE (tree);
2572             sym->etype = getSpec(sym->type);
2573             sym->lineDef = tree->lineno;
2574             sym->cdef = 1;
2575             sym->isref = 1;
2576             SPEC_STAT (sym->etype) = 1;
2577             SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2578                                      + element->offset;
2579             SPEC_ABSA(sym->etype) = 1;
2580             addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2581             allocGlobal (sym);
2582
2583             AST_VALUE (tree) = symbolVal(sym);
2584             TLVAL (tree) = 1;
2585             TRVAL (tree) = 0;
2586             tree->type = EX_VALUE;
2587             tree->left = NULL;
2588             tree->right = NULL;
2589         }
2590       #endif
2591
2592       return tree;
2593
2594       /*------------------------------------------------------------------*/
2595       /*----------------------------*/
2596       /*  ++/-- operation           */
2597       /*----------------------------*/
2598     case INC_OP:
2599     case DEC_OP:
2600       {
2601         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2602         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2603         if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2604           werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2605
2606         if (tree->right)
2607           RLVAL (tree) = 1;
2608         else
2609           LLVAL (tree) = 1;
2610         return tree;
2611       }
2612
2613       /*------------------------------------------------------------------*/
2614       /*----------------------------*/
2615       /*  bitwise and               */
2616       /*----------------------------*/
2617     case '&':                   /* can be unary   */
2618       /* if right is NULL then unary operation  */
2619       if (tree->right)          /* not an unary operation */
2620         {
2621
2622           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2623             {
2624               werror (E_BITWISE_OP);
2625               werror (W_CONTINUE, "left & right types are ");
2626               printTypeChain (LTYPE (tree), stderr);
2627               fprintf (stderr, ",");
2628               printTypeChain (RTYPE (tree), stderr);
2629               fprintf (stderr, "\n");
2630               goto errorTreeReturn;
2631             }
2632
2633           /* if they are both literal */
2634           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2635             {
2636               tree->type = EX_VALUE;
2637               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2638                                           valFromType (RETYPE (tree)), '&');
2639
2640               tree->right = tree->left = NULL;
2641               TETYPE (tree) = tree->opval.val->etype;
2642               TTYPE (tree) = tree->opval.val->type;
2643               return tree;
2644             }
2645
2646           /* see if this is a GETHBIT operation if yes
2647              then return that */
2648           {
2649             ast *otree = optimizeGetHbit (tree, resultType);
2650
2651             if (otree != tree)
2652               return decorateType (otree, RESULT_TYPE_NONE);
2653           }
2654
2655           /* see if this is a GETABIT operation if yes
2656              then return that */
2657           {
2658             ast *otree = optimizeGetAbit (tree, resultType);
2659
2660             if (otree != tree)
2661               return decorateType (otree, RESULT_TYPE_NONE);
2662           }
2663
2664           /* see if this is a GETBYTE operation if yes
2665              then return that */
2666           {
2667             ast *otree = optimizeGetByte (tree, resultType);
2668
2669             if (otree != tree)
2670               return decorateType (otree, RESULT_TYPE_NONE);
2671           }
2672
2673           /* see if this is a GETWORD operation if yes
2674              then return that */
2675           {
2676             ast *otree = optimizeGetWord (tree, resultType);
2677
2678             if (otree != tree)
2679               return decorateType (otree, RESULT_TYPE_NONE);
2680           }
2681
2682           /* if left is a literal exchange left & right */
2683           if (IS_LITERAL (LTYPE (tree)))
2684             {
2685               ast *tTree = tree->left;
2686               tree->left = tree->right;
2687               tree->right = tTree;
2688             }
2689
2690           /* if right is a literal and */
2691           /* we can find a 2nd literal in an and-tree then */
2692           /* rearrange the tree */
2693           if (IS_LITERAL (RTYPE (tree)))
2694             {
2695               ast *parent;
2696               ast *litTree = searchLitOp (tree, &parent, "&");
2697               if (litTree)
2698                 {
2699                   DEBUG_CF("&")
2700                   ast *tTree = litTree->left;
2701                   litTree->left = tree->right;
2702                   tree->right = tTree;
2703                   /* both operands in litTree are literal now */
2704                   decorateType (parent, resultType);
2705                 }
2706             }
2707
2708           LRVAL (tree) = RRVAL (tree) = 1;
2709
2710           TTYPE (tree) = computeType (LTYPE (tree),
2711                                       RTYPE (tree),
2712                                       resultType,
2713                                       tree->opval.op);
2714           TETYPE (tree) = getSpec (TTYPE (tree));
2715
2716           return tree;
2717         }
2718
2719       /*------------------------------------------------------------------*/
2720       /*----------------------------*/
2721       /*  address of                */
2722       /*----------------------------*/
2723       p = newLink (DECLARATOR);
2724       /* if bit field then error */
2725       if (IS_BITVAR (tree->left->etype))
2726         {
2727           werror (E_ILLEGAL_ADDR, "address of bit variable");
2728           goto errorTreeReturn;
2729         }
2730
2731       if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2732         {
2733           werror (E_ILLEGAL_ADDR, "address of register variable");
2734           goto errorTreeReturn;
2735         }
2736
2737       if (IS_FUNC (LTYPE (tree)))
2738         {
2739           // this ought to be ignored
2740           return (tree->left);
2741         }
2742
2743       if (IS_LITERAL(LTYPE(tree)))
2744         {
2745           werror (E_ILLEGAL_ADDR, "address of literal");
2746           goto errorTreeReturn;
2747         }
2748
2749      if (LRVAL (tree))
2750         {
2751           werror (E_LVALUE_REQUIRED, "address of");
2752           goto errorTreeReturn;
2753         }
2754       if (!LETYPE (tree))
2755         DCL_TYPE (p) = POINTER;
2756       else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2757         DCL_TYPE (p) = CPOINTER;
2758       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2759         DCL_TYPE (p) = FPOINTER;
2760       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2761         DCL_TYPE (p) = PPOINTER;
2762       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2763         DCL_TYPE (p) = IPOINTER;
2764       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2765         DCL_TYPE (p) = EEPPOINTER;
2766       else if (SPEC_OCLS(tree->left->etype))
2767           DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2768       else
2769           DCL_TYPE (p) = POINTER;
2770
2771       if (IS_AST_SYM_VALUE (tree->left))
2772         {
2773           AST_SYMBOL (tree->left)->addrtaken = 1;
2774           AST_SYMBOL (tree->left)->allocreq = 1;
2775         }
2776
2777       p->next = LTYPE (tree);
2778       TTYPE (tree) = p;
2779       TETYPE (tree) = getSpec (TTYPE (tree));
2780       LLVAL (tree) = 1;
2781       TLVAL (tree) = 1;
2782
2783       #if 0
2784       if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2785           && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2786         {
2787           symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2788                                       AST_SYMBOL(tree->left->right));
2789           AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2790                                     valueFromLit(element->offset));
2791           tree->left = NULL;
2792           tree->right = NULL;
2793           tree->type = EX_VALUE;
2794           tree->values.literalFromCast = 1;
2795         }
2796       #endif
2797
2798       return tree;
2799
2800       /*------------------------------------------------------------------*/
2801       /*----------------------------*/
2802       /*  bitwise or                */
2803       /*----------------------------*/
2804     case '|':
2805       /* if the rewrite succeeds then don't go any further */
2806       {
2807         ast *wtree = optimizeRRCRLC (tree);
2808         if (wtree != tree)
2809           return decorateType (wtree, RESULT_TYPE_NONE);
2810
2811         wtree = optimizeSWAP (tree);
2812         if (wtree != tree)
2813           return decorateType (wtree, RESULT_TYPE_NONE);
2814       }
2815
2816       /* if left is a literal exchange left & right */
2817       if (IS_LITERAL (LTYPE (tree)))
2818         {
2819           ast *tTree = tree->left;
2820           tree->left = tree->right;
2821           tree->right = tTree;
2822         }
2823
2824       /* if right is a literal and */
2825       /* we can find a 2nd literal in an or-tree then */
2826       /* rearrange the tree */
2827       if (IS_LITERAL (RTYPE (tree)))
2828         {
2829           ast *parent;
2830           ast *litTree = searchLitOp (tree, &parent, "|");
2831           if (litTree)
2832             {
2833               DEBUG_CF("|")
2834               ast *tTree = litTree->left;
2835               litTree->left = tree->right;
2836               tree->right = tTree;
2837               /* both operands in tTree are literal now */
2838               decorateType (parent, resultType);
2839             }
2840         }
2841       /* fall through */
2842
2843       /*------------------------------------------------------------------*/
2844       /*----------------------------*/
2845       /*  bitwise xor               */
2846       /*----------------------------*/
2847     case '^':
2848       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2849         {
2850           werror (E_BITWISE_OP);
2851           werror (W_CONTINUE, "left & right types are ");
2852           printTypeChain (LTYPE (tree), stderr);
2853           fprintf (stderr, ",");
2854           printTypeChain (RTYPE (tree), stderr);
2855           fprintf (stderr, "\n");
2856           goto errorTreeReturn;
2857         }
2858
2859       /* if they are both literal then rewrite the tree */
2860       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2861         {
2862           tree->type = EX_VALUE;
2863           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2864                                         valFromType (RETYPE (tree)),
2865                                         tree->opval.op);
2866           tree->right = tree->left = NULL;
2867           TETYPE (tree) = tree->opval.val->etype;
2868           TTYPE (tree) = tree->opval.val->type;
2869           return tree;
2870         }
2871
2872       /* if left is a literal exchange left & right */
2873       if (IS_LITERAL (LTYPE (tree)))
2874         {
2875           ast *tTree = tree->left;
2876           tree->left = tree->right;
2877           tree->right = tTree;
2878         }
2879
2880       /* if right is a literal and */
2881       /* we can find a 2nd literal in a xor-tree then */
2882       /* rearrange the tree */
2883       if (IS_LITERAL (RTYPE (tree)) &&
2884           tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2885         {
2886           ast *parent;
2887           ast *litTree = searchLitOp (tree, &parent, "^");
2888           if (litTree)
2889             {
2890               DEBUG_CF("^")
2891               ast *tTree = litTree->left;
2892               litTree->left = tree->right;
2893               tree->right = tTree;
2894               /* both operands in litTree are literal now */
2895               decorateType (parent, resultType);
2896             }
2897         }
2898
2899       LRVAL (tree) = RRVAL (tree) = 1;
2900
2901       TTYPE (tree) = computeType (LTYPE (tree),
2902                                   RTYPE (tree),
2903                                   resultType,
2904                                   tree->opval.op);
2905       TETYPE (tree) = getSpec (TTYPE (tree));
2906
2907       return tree;
2908
2909       /*------------------------------------------------------------------*/
2910       /*----------------------------*/
2911       /*  division                  */
2912       /*----------------------------*/
2913     case '/':
2914       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2915         {
2916           werror (E_INVALID_OP, "divide");
2917           goto errorTreeReturn;
2918         }
2919       /* if they are both literal then */
2920       /* rewrite the tree */
2921       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2922         {
2923           tree->type = EX_VALUE;
2924           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2925                                     valFromType (RETYPE (tree)));
2926           tree->right = tree->left = NULL;
2927           TETYPE (tree) = getSpec (TTYPE (tree) =
2928                                    tree->opval.val->type);
2929           return tree;
2930         }
2931
2932       LRVAL (tree) = RRVAL (tree) = 1;
2933
2934       TETYPE (tree) = getSpec (TTYPE (tree) =
2935                                computeType (LTYPE (tree),
2936                                             RTYPE (tree),
2937                                             resultType,
2938                                             tree->opval.op));
2939
2940       /* if right is a literal and */
2941       /* left is also a division by a literal then */
2942       /* rearrange the tree */
2943       if (IS_LITERAL (RTYPE (tree))
2944           /* avoid infinite loop */
2945           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2946         {
2947           ast *parent;
2948           ast *litTree = searchLitOp (tree, &parent, "/");
2949           if (litTree)
2950             {
2951               if (IS_LITERAL (RTYPE (litTree)))
2952                 {
2953                   /* foo_div */
2954                   DEBUG_CF("div r")
2955                   litTree->right = newNode ('*',
2956                                             litTree->right,
2957                                             copyAst (tree->right));
2958                   litTree->right->lineno = tree->lineno;
2959
2960                   tree->right->opval.val = constVal ("1");
2961                   decorateType (parent, resultType);
2962                 }
2963               else
2964                 {
2965                   /* litTree->left is literal: no gcse possible.
2966                      We can't call decorateType(parent, RESULT_TYPE_NONE), because
2967                      this would cause an infinit loop. */
2968                   parent->decorated = 1;
2969                   decorateType (litTree, resultType);
2970                 }
2971             }
2972         }
2973
2974       return tree;
2975
2976       /*------------------------------------------------------------------*/
2977       /*----------------------------*/
2978       /*            modulus         */
2979       /*----------------------------*/
2980     case '%':
2981       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2982         {
2983           werror (E_BITWISE_OP);
2984           werror (W_CONTINUE, "left & right types are ");
2985           printTypeChain (LTYPE (tree), stderr);
2986           fprintf (stderr, ",");
2987           printTypeChain (RTYPE (tree), stderr);
2988           fprintf (stderr, "\n");
2989           goto errorTreeReturn;
2990         }
2991       /* if they are both literal then */
2992       /* rewrite the tree */
2993       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2994         {
2995           tree->type = EX_VALUE;
2996           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2997                                     valFromType (RETYPE (tree)));
2998           tree->right = tree->left = NULL;
2999           TETYPE (tree) = getSpec (TTYPE (tree) =
3000                                    tree->opval.val->type);
3001           return tree;
3002         }
3003       LRVAL (tree) = RRVAL (tree) = 1;
3004       TETYPE (tree) = getSpec (TTYPE (tree) =
3005                                computeType (LTYPE (tree),
3006                                             RTYPE (tree),
3007                                             resultType,
3008                                             tree->opval.op));
3009       return tree;
3010
3011       /*------------------------------------------------------------------*/
3012       /*----------------------------*/
3013       /*  address dereference       */
3014       /*----------------------------*/
3015     case '*':                   /* can be unary  : if right is null then unary operation */
3016       if (!tree->right)
3017         {
3018           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3019             {
3020               werror (E_PTR_REQD);
3021               goto errorTreeReturn;
3022             }
3023
3024           if (LRVAL (tree))
3025             {
3026               werror (E_LVALUE_REQUIRED, "pointer deref");
3027               goto errorTreeReturn;
3028             }
3029           if (IS_ADDRESS_OF_OP(tree->left))
3030             {
3031               /* replace *&obj with obj */
3032               return tree->left->left;
3033             }
3034           TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3035           TETYPE (tree) = getSpec (TTYPE (tree));
3036           /* adjust the storage class */
3037           switch (DCL_TYPE(tree->left->ftype)) {
3038             case POINTER:
3039               SPEC_SCLS(TETYPE(tree)) = S_DATA;
3040               break;
3041             case FPOINTER:
3042               SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3043               break;
3044             case CPOINTER:
3045               SPEC_SCLS(TETYPE(tree)) = S_CODE;
3046               break;
3047             case GPOINTER:
3048               SPEC_SCLS (TETYPE (tree)) = 0;
3049               break;
3050             case PPOINTER:
3051               SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3052               break;
3053             case IPOINTER:
3054               SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3055               break;
3056             case EEPPOINTER:
3057               SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3058               break;
3059             case UPOINTER:
3060               SPEC_SCLS (TETYPE (tree)) = 0;
3061               break;
3062             case ARRAY:
3063             case FUNCTION:
3064               break;
3065           }
3066           return tree;
3067         }
3068
3069       /*------------------------------------------------------------------*/
3070       /*----------------------------*/
3071       /*      multiplication        */
3072       /*----------------------------*/
3073       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3074         {
3075           werror (E_INVALID_OP, "multiplication");
3076           goto errorTreeReturn;
3077         }
3078
3079       /* if they are both literal then */
3080       /* rewrite the tree */
3081       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3082         {
3083           tree->type = EX_VALUE;
3084           tree->opval.val = valMult (valFromType (LETYPE (tree)),
3085                                      valFromType (RETYPE (tree)));
3086           tree->right = tree->left = NULL;
3087           TETYPE (tree) = getSpec (TTYPE (tree) =
3088                                    tree->opval.val->type);
3089           return tree;
3090         }
3091
3092       /* if left is a literal exchange left & right */
3093       if (IS_LITERAL (LTYPE (tree)))
3094         {
3095           ast *tTree = tree->left;
3096           tree->left = tree->right;
3097           tree->right = tTree;
3098         }
3099
3100       /* if right is a literal and */
3101       /* we can find a 2nd literal in a mul-tree then */
3102       /* rearrange the tree */
3103       if (IS_LITERAL (RTYPE (tree)))
3104         {
3105           ast *parent;
3106           ast *litTree = searchLitOp (tree, &parent, "*");
3107           if (litTree)
3108             {
3109               DEBUG_CF("mul")
3110               ast *tTree = litTree->left;
3111               litTree->left = tree->right;
3112               tree->right = tTree;
3113               /* both operands in litTree are literal now */
3114               decorateType (parent, resultType);
3115             }
3116         }
3117
3118       LRVAL (tree) = RRVAL (tree) = 1;
3119       tree->left  = addCast (tree->left,  resultType, FALSE);
3120       tree->right = addCast (tree->right, resultType, FALSE);
3121       TETYPE (tree) = getSpec (TTYPE (tree) =
3122                                    computeType (LTYPE (tree),
3123                                                 RTYPE (tree),
3124                                                 resultType,
3125                                                 tree->opval.op));
3126
3127       return tree;
3128
3129       /*------------------------------------------------------------------*/
3130       /*----------------------------*/
3131       /*    unary '+' operator      */
3132       /*----------------------------*/
3133     case '+':
3134       /* if unary plus */
3135       if (!tree->right)
3136         {
3137           if (!IS_ARITHMETIC (LTYPE (tree)))
3138             {
3139               werror (E_UNARY_OP, '+');
3140               goto errorTreeReturn;
3141             }
3142
3143           /* if left is a literal then do it */
3144           if (IS_LITERAL (LTYPE (tree)))
3145             {
3146               tree->type = EX_VALUE;
3147               tree->opval.val = valFromType (LETYPE (tree));
3148               tree->left = NULL;
3149               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3150               return tree;
3151             }
3152           LRVAL (tree) = 1;
3153           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3154           return tree;
3155         }
3156
3157       /*------------------------------------------------------------------*/
3158       /*----------------------------*/
3159       /*      addition              */
3160       /*----------------------------*/
3161
3162       /* this is not a unary operation */
3163       /* if both pointers then problem */
3164       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3165           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3166         {
3167           werror (E_PTR_PLUS_PTR);
3168           goto errorTreeReturn;
3169         }
3170
3171       if (!IS_ARITHMETIC (LTYPE (tree)) &&
3172           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3173         {
3174           werror (E_PLUS_INVALID, "+");
3175           goto errorTreeReturn;
3176         }
3177
3178       if (!IS_ARITHMETIC (RTYPE (tree)) &&
3179           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3180         {
3181           werror (E_PLUS_INVALID, "+");
3182           goto errorTreeReturn;
3183         }
3184       /* if they are both literal then */
3185       /* rewrite the tree */
3186       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3187         {
3188           tree->type = EX_VALUE;
3189           tree->left  = addCast (tree->left,  resultType, TRUE);
3190           tree->right = addCast (tree->right, resultType, TRUE);
3191           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3192                                      valFromType (RETYPE (tree)));
3193           tree->right = tree->left = NULL;
3194           TETYPE (tree) = getSpec (TTYPE (tree) =
3195                                    tree->opval.val->type);
3196           return tree;
3197         }
3198
3199       /* if the right is a pointer or left is a literal
3200          xchange left & right */
3201       if (IS_ARRAY (RTYPE (tree)) ||
3202           IS_PTR (RTYPE (tree)) ||
3203           IS_LITERAL (LTYPE (tree)))
3204         {
3205           ast *tTree = tree->left;
3206           tree->left = tree->right;
3207           tree->right = tTree;
3208         }
3209
3210       /* if right is a literal and */
3211       /* left is also an addition/subtraction with a literal then */
3212       /* rearrange the tree */
3213       if (IS_LITERAL (RTYPE (tree)))
3214         {
3215           ast *litTree, *parent;
3216           litTree = searchLitOp (tree, &parent, "+-");
3217           if (litTree)
3218             {
3219               if (litTree->opval.op == '+')
3220                 {
3221                   /* foo_aa */
3222                   DEBUG_CF("+ 1 AA")
3223                   ast *tTree = litTree->left;
3224                   litTree->left = tree->right;
3225                   tree->right = tree->left;
3226                   tree->left = tTree;
3227                 }
3228               else if (litTree->opval.op == '-')
3229                 {
3230                   if (IS_LITERAL (RTYPE (litTree)))
3231                     {
3232                       DEBUG_CF("+ 2 ASR")
3233                       /* foo_asr */
3234                       ast *tTree = litTree->left;
3235                       litTree->left = tree->right;
3236                       tree->right = tTree;
3237                     }
3238                   else
3239                     {
3240                       DEBUG_CF("+ 3 ASL")
3241                       /* foo_asl */
3242                       ast *tTree = litTree->right;
3243                       litTree->right = tree->right;
3244                       tree->right = tTree;
3245                       litTree->opval.op = '+';
3246                       tree->opval.op = '-';
3247                     }
3248                 }
3249               decorateType (parent, resultType);
3250             }
3251         }
3252
3253       LRVAL (tree) = RRVAL (tree) = 1;
3254       /* if the left is a pointer */
3255       if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3256         TETYPE (tree) = getSpec (TTYPE (tree) =
3257                                  LTYPE (tree));
3258       else
3259         {
3260           tree->left  = addCast (tree->left,  resultType, TRUE);
3261           tree->right = addCast (tree->right, resultType, TRUE);
3262           TETYPE (tree) = getSpec (TTYPE (tree) =
3263                                      computeType (LTYPE (tree),
3264                                                   RTYPE (tree),
3265                                                   resultType,
3266                                                   tree->opval.op));
3267         }
3268
3269       return tree;
3270
3271       /*------------------------------------------------------------------*/
3272       /*----------------------------*/
3273       /*      unary '-'             */
3274       /*----------------------------*/
3275     case '-':                   /* can be unary   */
3276       /* if right is null then unary */
3277       if (!tree->right)
3278         {
3279
3280           if (!IS_ARITHMETIC (LTYPE (tree)))
3281             {
3282               werror (E_UNARY_OP, tree->opval.op);
3283               goto errorTreeReturn;
3284             }
3285
3286           /* if left is a literal then do it */
3287           if (IS_LITERAL (LTYPE (tree)))
3288             {
3289               tree->type = EX_VALUE;
3290               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3291               tree->left = NULL;
3292               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3293               return tree;
3294             }
3295           tree->left  = addCast (tree->left, resultType, TRUE);
3296           TETYPE (tree) = getSpec (TTYPE (tree) =
3297                                      computeType (LTYPE (tree),
3298                                                   NULL,
3299                                                   resultType,
3300                                                   tree->opval.op));
3301           LRVAL (tree) = 1;
3302           return tree;
3303         }
3304
3305       /*------------------------------------------------------------------*/
3306       /*----------------------------*/
3307       /*    subtraction             */
3308       /*----------------------------*/
3309
3310       if (!(IS_PTR (LTYPE (tree)) ||
3311             IS_ARRAY (LTYPE (tree)) ||
3312             IS_ARITHMETIC (LTYPE (tree))))
3313         {
3314           werror (E_PLUS_INVALID, "-");
3315           goto errorTreeReturn;
3316         }
3317
3318       if (!(IS_PTR (RTYPE (tree)) ||
3319             IS_ARRAY (RTYPE (tree)) ||
3320             IS_ARITHMETIC (RTYPE (tree))))
3321         {
3322           werror (E_PLUS_INVALID, "-");
3323           goto errorTreeReturn;
3324         }
3325
3326       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3327           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3328             IS_INTEGRAL (RTYPE (tree))))
3329         {
3330           werror (E_PLUS_INVALID, "-");
3331           goto errorTreeReturn;
3332         }
3333
3334       /* if they are both literal then */
3335       /* rewrite the tree */
3336       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3337         {
3338           tree->type = EX_VALUE;
3339           tree->left  = addCast (tree->left,  resultType, TRUE);
3340           tree->right = addCast (tree->right, resultType, TRUE);
3341           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3342                                       valFromType (RETYPE (tree)));
3343           tree->right = tree->left = NULL;
3344           TETYPE (tree) = getSpec (TTYPE (tree) =
3345                                    tree->opval.val->type);
3346           return tree;
3347         }
3348
3349       /* if the left & right are equal then zero */
3350       if (isAstEqual (tree->left, tree->right))
3351         {
3352           tree->type = EX_VALUE;
3353           tree->left = tree->right = NULL;
3354           tree->opval.val = constVal ("0");
3355           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3356           return tree;
3357         }
3358
3359       /* if both of them are pointers or arrays then */
3360       /* the result is going to be an integer        */
3361       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3362           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3363         TETYPE (tree) = TTYPE (tree) = newIntLink ();
3364       else
3365         /* if only the left is a pointer */
3366         /* then result is a pointer      */
3367       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3368         TETYPE (tree) = getSpec (TTYPE (tree) =
3369                                  LTYPE (tree));
3370       else
3371         {
3372           tree->left  = addCast (tree->left,  resultType, TRUE);
3373           tree->right = addCast (tree->right, resultType, TRUE);
3374
3375           TETYPE (tree) = getSpec (TTYPE (tree) =
3376                                      computeType (LTYPE (tree),
3377                                                   RTYPE (tree),
3378                                                   resultType,
3379                                                   tree->opval.op));
3380         }
3381
3382       LRVAL (tree) = RRVAL (tree) = 1;
3383
3384       /* if right is a literal and */
3385       /* left is also an addition/subtraction with a literal then */
3386       /* rearrange the tree */
3387       if (IS_LITERAL (RTYPE (tree))
3388           /* avoid infinite loop */
3389           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3390         {
3391           ast *litTree, *litParent;
3392           litTree = searchLitOp (tree, &litParent, "+-");
3393           if (litTree)
3394             {
3395               if (litTree->opval.op == '+')
3396                 {
3397                   /* foo_sa */
3398                   DEBUG_CF("- 1 SA")
3399                   ast *tTree = litTree->left;
3400                   litTree->left = litTree->right;
3401                   litTree->right = tree->right;
3402                   tree->right = tTree;
3403                   tree->opval.op = '+';
3404                   litTree->opval.op = '-';
3405                 }
3406               else if (litTree->opval.op == '-')
3407                 {
3408                   if (IS_LITERAL (RTYPE (litTree)))
3409                     {
3410                       /* foo_ssr */
3411                       DEBUG_CF("- 2 SSR")
3412                       ast *tTree = litTree->left;
3413                       litTree->left = tree->right;
3414                       tree->right = litParent->left;
3415                       litParent->left = tTree;
3416                       litTree->opval.op = '+';
3417
3418                       tree->decorated = 0;
3419                       decorateType (tree, resultType);
3420                     }
3421                   else
3422                     {
3423                       /* foo_ssl */
3424                       DEBUG_CF("- 3 SSL")
3425                       ast *tTree = litTree->right;
3426                       litTree->right = tree->right;
3427                       tree->right = tTree;
3428                     }
3429                 }
3430               decorateType (litParent, resultType);
3431             }
3432         }
3433       return tree;
3434
3435       /*------------------------------------------------------------------*/
3436       /*----------------------------*/
3437       /*    complement              */
3438       /*----------------------------*/
3439     case '~':
3440       /* can be only integral type */
3441       if (!IS_INTEGRAL (LTYPE (tree)))
3442         {
3443           werror (E_UNARY_OP, tree->opval.op);
3444           goto errorTreeReturn;
3445         }
3446
3447       /* if left is a literal then do it */
3448       if (IS_LITERAL (LTYPE (tree)))
3449         {
3450           tree->type = EX_VALUE;
3451           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3452           tree->left = NULL;
3453           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3454           return addCast (tree, resultType, TRUE);
3455         }
3456
3457       if (resultType == RESULT_TYPE_BIT &&
3458           IS_UNSIGNED (tree->left->etype) &&
3459           getSize (tree->left->etype) < INTSIZE)
3460         {
3461           /* promotion rules are responsible for this strange result:
3462              bit -> int -> ~int -> bit
3463              uchar -> int -> ~int -> bit
3464           */
3465           werror(W_COMPLEMENT);
3466
3467           /* optimize bit-result, even if we optimize a buggy source */
3468           tree->type = EX_VALUE;
3469           tree->opval.val = constVal ("1");
3470         }
3471       else
3472         tree->left = addCast (tree->left, resultType, TRUE);
3473       LRVAL (tree) = 1;
3474       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3475       return tree;
3476
3477       /*------------------------------------------------------------------*/
3478       /*----------------------------*/
3479       /*           not              */
3480       /*----------------------------*/
3481     case '!':
3482       /* can be pointer */
3483       if (!IS_ARITHMETIC (LTYPE (tree)) &&
3484           !IS_PTR (LTYPE (tree)) &&
3485           !IS_ARRAY (LTYPE (tree)))
3486         {
3487           werror (E_UNARY_OP, tree->opval.op);
3488           goto errorTreeReturn;
3489         }
3490
3491       /* if left is a literal then do it */
3492       if (IS_LITERAL (LTYPE (tree)))
3493         {
3494           tree->type = EX_VALUE;
3495           tree->opval.val = valNot (valFromType (LETYPE (tree)));
3496           tree->left = NULL;
3497           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3498           return tree;
3499         }
3500       LRVAL (tree) = 1;
3501       TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3502       return tree;
3503
3504       /*------------------------------------------------------------------*/
3505       /*----------------------------*/
3506       /*           shift            */
3507       /*----------------------------*/
3508     case RRC:
3509     case RLC:
3510     case SWAP:
3511       TTYPE (tree) = LTYPE (tree);
3512       TETYPE (tree) = LETYPE (tree);
3513       return tree;
3514
3515     case GETHBIT:
3516     case GETABIT:
3517       TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3518       return tree;
3519
3520     case GETBYTE:
3521       TTYPE (tree) = TETYPE (tree) = newCharLink();
3522       return tree;
3523
3524     case GETWORD:
3525       TTYPE (tree) = TETYPE (tree) = newIntLink();
3526       return tree;
3527
3528     case LEFT_OP:
3529     case RIGHT_OP:
3530       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3531         {
3532           werror (E_SHIFT_OP_INVALID);
3533           werror (W_CONTINUE, "left & right types are ");
3534           printTypeChain (LTYPE (tree), stderr);
3535           fprintf (stderr, ",");
3536           printTypeChain (RTYPE (tree), stderr);
3537           fprintf (stderr, "\n");
3538           goto errorTreeReturn;
3539         }
3540
3541       /* make smaller type only if it's a LEFT_OP */
3542       if (tree->opval.op == LEFT_OP)
3543         tree->left = addCast (tree->left, resultType, TRUE);
3544
3545       /* if they are both literal then */
3546       /* rewrite the tree */
3547       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3548         {
3549           tree->type = EX_VALUE;
3550           tree->opval.val = valShift (valFromType (LETYPE (tree)),
3551                                       valFromType (RETYPE (tree)),
3552                                       (tree->opval.op == LEFT_OP ? 1 : 0));
3553           tree->right = tree->left = NULL;
3554           TETYPE (tree) = getSpec (TTYPE (tree) =
3555                                    tree->opval.val->type);
3556           return tree;
3557         }
3558
3559       /* see if this is a GETBYTE operation if yes
3560          then return that */
3561       {
3562         ast *otree = optimizeGetByte (tree, resultType);
3563
3564         if (otree != tree)
3565           return decorateType (otree, RESULT_TYPE_NONE);
3566       }
3567
3568       /* see if this is a GETWORD operation if yes
3569          then return that */
3570       {
3571         ast *otree = optimizeGetWord (tree, resultType);
3572
3573         if (otree != tree)
3574           return decorateType (otree, RESULT_TYPE_NONE);
3575       }
3576
3577       LRVAL (tree) = RRVAL (tree) = 1;
3578       if (tree->opval.op == LEFT_OP)
3579         {
3580           TETYPE (tree) = getSpec (TTYPE (tree) =
3581                                        computeType (LTYPE (tree),
3582                                                     NULL,
3583                                                     resultType,
3584                                                     tree->opval.op));
3585         }
3586       else /* RIGHT_OP */
3587         {
3588           /* no promotion necessary */
3589           TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3590           if (IS_LITERAL (TTYPE (tree)))
3591             SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3592         }
3593
3594       /* if only the right side is a literal & we are
3595          shifting more than size of the left operand then zero */
3596       if (IS_LITERAL (RTYPE (tree)) &&
3597           ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3598           (getSize (TETYPE (tree)) * 8))
3599         {
3600           if (tree->opval.op==LEFT_OP ||
3601               (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3602             {
3603               lineno=tree->lineno;
3604               werror (W_SHIFT_CHANGED,
3605                       (tree->opval.op == LEFT_OP ? "left" : "right"));
3606               tree->type = EX_VALUE;
3607               tree->left = tree->right = NULL;
3608               tree->opval.val = constVal ("0");
3609               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3610               return tree;
3611             }
3612         }
3613
3614       return tree;
3615
3616       /*------------------------------------------------------------------*/
3617       /*----------------------------*/
3618       /*         casting            */
3619       /*----------------------------*/
3620     case CAST:                  /* change the type   */
3621       /* cannot cast to an aggregate type */
3622       if (IS_AGGREGATE (LTYPE (tree)))
3623         {
3624           werror (E_CAST_ILLEGAL);
3625           goto errorTreeReturn;
3626         }
3627
3628       /* make sure the type is complete and sane */
3629       changePointer(LTYPE(tree));
3630       checkTypeSanity(LETYPE(tree), "(cast)");
3631
3632       /* if 'from' and 'to' are the same remove the superflous cast, */
3633       /* this helps other optimizations */
3634       if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3635         {
3636           return tree->right;
3637         }
3638
3639       /* If code memory is read only, then pointers to code memory */
3640       /* implicitly point to constants -- make this explicit       */
3641       {
3642         sym_link *t = LTYPE(tree);
3643         while (t && t->next)
3644           {
3645             if (IS_CODEPTR(t) && port->mem.code_ro)
3646               {
3647                 if (IS_SPEC(t->next))
3648                   SPEC_CONST (t->next) = 1;
3649                 else
3650                   DCL_PTR_CONST (t->next) = 1;
3651               }
3652             t = t->next;
3653           }
3654       }
3655
3656 #if 0
3657       /* if the right is a literal replace the tree */
3658       if (IS_LITERAL (RETYPE (tree))) {
3659               if (!IS_PTR (LTYPE (tree))) {
3660                       tree->type = EX_VALUE;
3661                       tree->opval.val =
3662                               valCastLiteral (LTYPE (tree),
3663                                               floatFromVal (valFromType (RETYPE (tree))));
3664                       tree->left = NULL;
3665                       tree->right = NULL;
3666                       TTYPE (tree) = tree->opval.val->type;
3667                       tree->values.literalFromCast = 1;
3668               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3669                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
3670                       sym_link *rest = LTYPE(tree)->next;
3671                       werror(W_LITERAL_GENERIC);
3672                       TTYPE(tree) = newLink(DECLARATOR);
3673                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
3674                       TTYPE(tree)->next = rest;
3675                       tree->left->opval.lnk = TTYPE(tree);
3676                       LRVAL (tree) = 1;
3677               } else {
3678                       TTYPE (tree) = LTYPE (tree);
3679                       LRVAL (tree) = 1;
3680               }
3681       } else {
3682               TTYPE (tree) = LTYPE (tree);
3683               LRVAL (tree) = 1;
3684       }
3685 #else
3686 #if 0 // this is already checked, now this could be explicit
3687       /* if pointer to struct then check names */
3688       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3689           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3690           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3691         {
3692           werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3693                  SPEC_STRUCT(LETYPE(tree))->tag);
3694         }
3695 #endif
3696       if (IS_ADDRESS_OF_OP(tree->right)
3697           && IS_AST_SYM_VALUE (tree->right->left)
3698           && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3699
3700         symbol * sym = AST_SYMBOL (tree->right->left);
3701         unsigned int gptype = 0;
3702         unsigned int addr = SPEC_ADDR (sym->etype);
3703
3704         if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3705           {
3706             switch (SPEC_SCLS (sym->etype))
3707               {
3708               case S_CODE:
3709                 gptype = GPTYPE_CODE;
3710                 break;
3711               case S_XDATA:
3712                 gptype = GPTYPE_FAR;
3713                 break;
3714               case S_DATA:
3715               case S_IDATA:
3716                 gptype = GPTYPE_NEAR;
3717                 break;
3718               case S_PDATA:
3719                 gptype = GPTYPE_XSTACK;
3720                 break;
3721               default:
3722                 gptype = 0;
3723               }
3724             addr |= gptype << (8*(GPTRSIZE - 1));
3725           }
3726
3727         tree->type = EX_VALUE;
3728         tree->opval.val =
3729           valCastLiteral (LTYPE (tree), addr);
3730         TTYPE (tree) = tree->opval.val->type;
3731         TETYPE (tree) = getSpec (TTYPE (tree));
3732         tree->left = NULL;
3733         tree->right = NULL;
3734         tree->values.literalFromCast = 1;
3735         return tree;
3736       }
3737
3738       /* handle offsetof macro:            */
3739       /* #define offsetof(TYPE, MEMBER) \  */
3740       /* ((unsigned) &((TYPE *)0)->MEMBER) */
3741       if (IS_ADDRESS_OF_OP(tree->right)
3742           && IS_AST_OP (tree->right->left)
3743           && tree->right->left->opval.op == PTR_OP
3744           && IS_AST_OP (tree->right->left->left)
3745           && tree->right->left->left->opval.op == CAST
3746           && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3747
3748         symbol *element = getStructElement (
3749           SPEC_STRUCT (LETYPE(tree->right->left)),
3750           AST_SYMBOL(tree->right->left->right)
3751         );
3752
3753         if (element) {
3754           tree->type = EX_VALUE;
3755           tree->opval.val = valCastLiteral (
3756             LTYPE (tree),
3757             element->offset
3758             + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3759           );
3760
3761           TTYPE (tree) = tree->opval.val->type;
3762           TETYPE (tree) = getSpec (TTYPE (tree));
3763           tree->left = NULL;
3764           tree->right = NULL;
3765           return tree;
3766         }
3767       }
3768
3769       /* if the right is a literal replace the tree */
3770       if (IS_LITERAL (RETYPE (tree))) {
3771         #if 0
3772         if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3773           /* rewrite      (type *)litaddr
3774              as           &temp
3775              and define   type at litaddr temp
3776              (but only if type's storage class is not generic)
3777           */
3778           ast *newTree = newNode ('&', NULL, NULL);
3779           symbol *sym;
3780
3781           TTYPE (newTree) = LTYPE (tree);
3782           TETYPE (newTree) = getSpec(LTYPE (tree));
3783
3784           /* define a global symbol at the casted address*/
3785           sym = newSymbol(genSymName (0), 0);
3786           sym->type = LTYPE (tree)->next;
3787           if (!sym->type)
3788             sym->type = newLink (V_VOID);
3789           sym->etype = getSpec(sym->type);
3790           SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3791           sym->lineDef = tree->lineno;
3792           sym->cdef = 1;
3793           sym->isref = 1;
3794           SPEC_STAT (sym->etype) = 1;
3795           SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3796           SPEC_ABSA(sym->etype) = 1;
3797           addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3798           allocGlobal (sym);
3799
3800           newTree->left = newAst_VALUE(symbolVal(sym));
3801           newTree->left->lineno = tree->lineno;
3802           LTYPE (newTree) = sym->type;
3803           LETYPE (newTree) = sym->etype;
3804           LLVAL (newTree) = 1;
3805           LRVAL (newTree) = 0;
3806           TLVAL (newTree) = 1;
3807           return newTree;
3808         }
3809         #endif
3810         if (!IS_PTR (LTYPE (tree))) {
3811           tree->type = EX_VALUE;
3812           tree->opval.val =
3813           valCastLiteral (LTYPE (tree),
3814                           floatFromVal (valFromType (RTYPE (tree))));
3815           TTYPE (tree) = tree->opval.val->type;
3816           tree->left = NULL;
3817           tree->right = NULL;
3818           tree->values.literalFromCast = 1;
3819           TETYPE (tree) = getSpec (TTYPE (tree));
3820           return tree;
3821         }
3822       }
3823       TTYPE (tree) = LTYPE (tree);
3824       LRVAL (tree) = 1;
3825
3826 #endif
3827       TETYPE (tree) = getSpec (TTYPE (tree));
3828
3829       return tree;
3830
3831       /*------------------------------------------------------------------*/
3832       /*----------------------------*/
3833       /*       logical &&, ||       */
3834       /*----------------------------*/
3835     case AND_OP:
3836     case OR_OP:
3837       /* each must be arithmetic type or be a pointer */
3838       if (!IS_PTR (LTYPE (tree)) &&
3839           !IS_ARRAY (LTYPE (tree)) &&
3840           !IS_INTEGRAL (LTYPE (tree)))
3841         {
3842           werror (E_COMPARE_OP);
3843           goto errorTreeReturn;
3844         }
3845
3846       if (!IS_PTR (RTYPE (tree)) &&
3847           !IS_ARRAY (RTYPE (tree)) &&
3848           !IS_INTEGRAL (RTYPE (tree)))
3849         {
3850           werror (E_COMPARE_OP);
3851           goto errorTreeReturn;
3852         }
3853       /* if they are both literal then */
3854       /* rewrite the tree */
3855       if (IS_LITERAL (RTYPE (tree)) &&
3856           IS_LITERAL (LTYPE (tree)))
3857         {
3858           tree->type = EX_VALUE;
3859           tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3860                                            valFromType (RTYPE (tree)),
3861                                            tree->opval.op);
3862           tree->right = tree->left = NULL;
3863           TETYPE (tree) = getSpec (TTYPE (tree) =
3864                                    tree->opval.val->type);
3865           return tree;
3866         }
3867       LRVAL (tree) = RRVAL (tree) = 1;
3868       TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3869       return tree;
3870
3871       /*------------------------------------------------------------------*/
3872       /*----------------------------*/
3873       /*     comparison operators   */
3874       /*----------------------------*/
3875     case '>':
3876     case '<':
3877     case LE_OP:
3878     case GE_OP:
3879     case EQ_OP:
3880     case NE_OP:
3881       {
3882         ast *lt = optimizeCompare (tree);
3883
3884         if (tree != lt)
3885           return lt;
3886       }
3887
3888       /* if they are pointers they must be castable */
3889       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3890         {
3891           if (tree->opval.op==EQ_OP &&
3892               !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3893             // we cannot cast a gptr to a !gptr: switch the leaves
3894             struct ast *s=tree->left;
3895             tree->left=tree->right;
3896             tree->right=s;
3897           }
3898           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3899             {
3900               werror (E_COMPARE_OP);
3901               fprintf (stderr, "comparing type ");
3902               printTypeChain (LTYPE (tree), stderr);
3903               fprintf (stderr, "to type ");
3904               printTypeChain (RTYPE (tree), stderr);
3905               fprintf (stderr, "\n");
3906               goto errorTreeReturn;
3907             }
3908         }
3909       /* else they should be promotable to one another */
3910       else
3911         {
3912           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3913                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3914
3915             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3916               {
3917                 werror (E_COMPARE_OP);
3918                 fprintf (stderr, "comparing type ");
3919                 printTypeChain (LTYPE (tree), stderr);
3920                 fprintf (stderr, "to type ");
3921                 printTypeChain (RTYPE (tree), stderr);
3922                 fprintf (stderr, "\n");
3923                 goto errorTreeReturn;
3924               }
3925         }
3926
3927       /* if unsigned value < 0  then always false */
3928       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3929       if (SPEC_USIGN(LETYPE(tree)) &&
3930           !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3931           IS_LITERAL(RTYPE(tree))  &&
3932           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3933         {
3934           if (tree->opval.op == '<')
3935             {
3936               return tree->right;
3937             }
3938           if (tree->opval.op == '>')
3939             {
3940               if (resultType == RESULT_TYPE_IFX)
3941                 {
3942                   /* the parent is an ifx: */
3943                   /* if (unsigned value) */
3944                   return tree->left;
3945                 }
3946
3947               /* (unsigned value) ? 1 : 0 */
3948               tree->opval.op = '?';
3949               tree->right = newNode (':',
3950                                      newAst_VALUE (constVal ("1")),
3951                                      tree->right); /* val 0 */
3952               tree->right->lineno = tree->lineno;
3953               tree->right->left->lineno = tree->lineno;
3954               tree->decorated = 0;
3955               return decorateType (tree, resultType);
3956             }
3957         }
3958
3959       /* 'ifx (op == 0)' -> 'ifx (!(op))' */
3960       if (IS_LITERAL(RTYPE(tree))  &&
3961           floatFromVal (valFromType (RETYPE (tree))) == 0 &&
3962           tree->opval.op == EQ_OP &&
3963           resultType == RESULT_TYPE_IFX)
3964         {
3965           tree->opval.op = '!';
3966           tree->right = NULL;
3967           tree->decorated = 0;
3968           return decorateType (tree, resultType);
3969         }
3970
3971       /* if they are both literal then */
3972       /* rewrite the tree */
3973       if (IS_LITERAL (RTYPE (tree)) &&
3974           IS_LITERAL (LTYPE (tree)))
3975         {
3976           tree->type = EX_VALUE;
3977           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3978                                         valFromType (RETYPE (tree)),
3979                                         tree->opval.op);
3980           tree->right = tree->left = NULL;
3981           TETYPE (tree) = getSpec (TTYPE (tree) =
3982                                    tree->opval.val->type);
3983           return tree;
3984         }
3985       /* if one is 'signed char ' and the other one is 'unsigned char' */
3986       /* it's necessary to promote to int */
3987       if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
3988           (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
3989         {
3990           /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
3991              if it's possible to use a 'signed char' */
3992
3993               /* is left a 'unsigned char'? */
3994           if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
3995               /* the value range of a 'unsigned char' is 0...255;
3996                  if the actual value is < 128 it can be changed to signed */
3997               (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
3998             {
3999               /* now we've got 2 'signed char'! */
4000               SPEC_USIGN (RETYPE (tree)) = 0;
4001             }
4002                    /* same test for the left operand: */
4003           else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4004               (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4005             {
4006               SPEC_USIGN (LETYPE (tree)) = 0;
4007             }
4008           else
4009             {
4010               werror (W_CMP_SU_CHAR);
4011               tree->left  = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4012               tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4013             }
4014         }
4015
4016       LRVAL (tree) = RRVAL (tree) = 1;
4017       TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4018       return tree;
4019
4020       /*------------------------------------------------------------------*/
4021       /*----------------------------*/
4022       /*             sizeof         */
4023       /*----------------------------*/
4024     case SIZEOF:                /* evaluate wihout code generation */
4025       /* change the type to a integer */
4026       {
4027         int size = getSize (tree->right->ftype);
4028         SNPRINTF(buffer, sizeof(buffer), "%d", size);
4029         if (!size && !IS_VOID(tree->right->ftype))
4030           werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4031       }
4032       tree->type = EX_VALUE;
4033       tree->opval.val = constVal (buffer);
4034       tree->right = tree->left = NULL;
4035       TETYPE (tree) = getSpec (TTYPE (tree) =
4036                                tree->opval.val->type);
4037       return tree;
4038
4039       /*------------------------------------------------------------------*/
4040       /*----------------------------*/
4041       /*             typeof         */
4042       /*----------------------------*/
4043     case TYPEOF:
4044         /* return typeof enum value */
4045         tree->type = EX_VALUE;
4046         {
4047             int typeofv = 0;
4048             if (IS_SPEC(tree->right->ftype)) {
4049                 switch (SPEC_NOUN(tree->right->ftype)) {
4050                 case V_INT:
4051                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4052                     else typeofv = TYPEOF_INT;
4053                     break;
4054                 case V_FLOAT:
4055                     typeofv = TYPEOF_FLOAT;
4056                     break;
4057                 case V_FIXED16X16:
4058                     typeofv = TYPEOF_FIXED16X16;
4059                     break;
4060                 case V_CHAR:
4061                     typeofv = TYPEOF_CHAR;
4062                     break;
4063                 case V_VOID:
4064                     typeofv = TYPEOF_VOID;
4065                     break;
4066                 case V_STRUCT:
4067                     typeofv = TYPEOF_STRUCT;
4068                     break;
4069                 case V_BITFIELD:
4070                     typeofv = TYPEOF_BITFIELD;
4071                     break;
4072                 case V_BIT:
4073                     typeofv = TYPEOF_BIT;
4074                     break;
4075                 case V_SBIT:
4076                     typeofv = TYPEOF_SBIT;
4077                     break;
4078                 default:
4079                     break;
4080                 }
4081             } else {
4082                 switch (DCL_TYPE(tree->right->ftype)) {
4083                 case POINTER:
4084                     typeofv = TYPEOF_POINTER;
4085                     break;
4086                 case FPOINTER:
4087                     typeofv = TYPEOF_FPOINTER;
4088                     break;
4089                 case CPOINTER:
4090                     typeofv = TYPEOF_CPOINTER;
4091                     break;
4092                 case GPOINTER:
4093                     typeofv = TYPEOF_GPOINTER;
4094                     break;
4095                 case PPOINTER:
4096                     typeofv = TYPEOF_PPOINTER;
4097                     break;
4098                 case IPOINTER:
4099                     typeofv = TYPEOF_IPOINTER;
4100                     break;
4101                 case ARRAY:
4102                     typeofv = TYPEOF_ARRAY;
4103                     break;
4104                 case FUNCTION:
4105                     typeofv = TYPEOF_FUNCTION;
4106                     break;
4107                 default:
4108                     break;
4109                 }
4110             }
4111             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4112             tree->opval.val = constVal (buffer);
4113             tree->right = tree->left = NULL;
4114             TETYPE (tree) = getSpec (TTYPE (tree) =
4115                                      tree->opval.val->type);
4116         }
4117         return tree;
4118       /*------------------------------------------------------------------*/
4119       /*----------------------------*/
4120       /* conditional operator  '?'  */
4121       /*----------------------------*/
4122     case '?':
4123       /* the type is value of the colon operator (on the right) */
4124       assert (IS_COLON_OP (tree->right));
4125       /* if already known then replace the tree : optimizer will do it
4126          but faster to do it here */
4127       if (IS_LITERAL (LTYPE (tree)))
4128         {
4129           if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4130             return decorateType (tree->right->left, resultTypeProp);
4131           else
4132             return decorateType (tree->right->right, resultTypeProp);
4133         }
4134       else
4135         {
4136           tree->right = decorateType (tree->right, resultTypeProp);
4137           TTYPE (tree) = RTYPE (tree);
4138           TETYPE (tree) = getSpec (TTYPE (tree));
4139         }
4140       return tree;
4141
4142     case ':':
4143       /* if they don't match we have a problem */
4144       if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4145           (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4146         {
4147           werror (E_TYPE_MISMATCH, "conditional operator", " ");
4148           goto errorTreeReturn;
4149         }
4150
4151       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4152                                   resultType, tree->opval.op);
4153       TETYPE (tree) = getSpec (TTYPE (tree));
4154       return tree;
4155
4156
4157 #if 0 // assignment operators are converted by the parser
4158       /*------------------------------------------------------------------*/
4159       /*----------------------------*/
4160       /*    assignment operators    */
4161       /*----------------------------*/
4162     case MUL_ASSIGN:
4163     case DIV_ASSIGN:
4164       /* for these it must be both must be integral */
4165       if (!IS_ARITHMETIC (LTYPE (tree)) ||
4166           !IS_ARITHMETIC (RTYPE (tree)))
4167         {
4168           werror (E_OPS_INTEGRAL);
4169           goto errorTreeReturn;
4170         }
4171       RRVAL (tree) = 1;
4172       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4173
4174       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4175         werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4176
4177       if (LRVAL (tree))
4178         {
4179           werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4180           goto errorTreeReturn;
4181         }
4182       LLVAL (tree) = 1;
4183
4184       return tree;
4185
4186     case AND_ASSIGN:
4187     case OR_ASSIGN:
4188     case XOR_ASSIGN:
4189     case RIGHT_ASSIGN:
4190     case LEFT_ASSIGN:
4191       /* for these it must be both must be integral */
4192       if (!IS_INTEGRAL (LTYPE (tree)) ||
4193           !IS_INTEGRAL (RTYPE (tree)))
4194         {
4195           werror (E_OPS_INTEGRAL);
4196           goto errorTreeReturn;
4197         }
4198       RRVAL (tree) = 1;
4199       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4200
4201       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4202         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4203
4204       if (LRVAL (tree))
4205         {
4206           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4207           goto errorTreeReturn;
4208         }
4209       LLVAL (tree) = 1;
4210
4211       return tree;
4212
4213       /*------------------------------------------------------------------*/
4214       /*----------------------------*/
4215       /*    -= operator             */
4216       /*----------------------------*/
4217     case SUB_ASSIGN:
4218       if (!(IS_PTR (LTYPE (tree)) ||
4219             IS_ARITHMETIC (LTYPE (tree))))
4220         {
4221           werror (E_PLUS_INVALID, "-=");
4222           goto errorTreeReturn;
4223         }
4224
4225       if (!(IS_PTR (RTYPE (tree)) ||
4226             IS_ARITHMETIC (RTYPE (tree))))
4227         {
4228           werror (E_PLUS_INVALID, "-=");
4229           goto errorTreeReturn;
4230         }
4231       RRVAL (tree) = 1;
4232       TETYPE (tree) = getSpec (TTYPE (tree) =
4233                                computeType (LTYPE (tree),
4234                                             RTYPE (tree),
4235                                             RESULT_TYPE_NOPROM,
4236                                             tree->opval.op));
4237
4238       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4239         werror (E_CODE_WRITE, "-=");
4240
4241       if (LRVAL (tree))
4242         {
4243           werror (E_LVALUE_REQUIRED, "-=");
4244           goto errorTreeReturn;
4245         }
4246       LLVAL (tree) = 1;
4247
4248       return tree;
4249
4250       /*------------------------------------------------------------------*/
4251       /*----------------------------*/
4252       /*          += operator       */
4253       /*----------------------------*/
4254     case ADD_ASSIGN:
4255       /* this is not a unary operation */
4256       /* if both pointers then problem */
4257       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4258         {
4259           werror (E_PTR_PLUS_PTR);
4260           goto errorTreeReturn;
4261         }
4262
4263       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4264         {
4265           werror (E_PLUS_INVALID, "+=");
4266           goto errorTreeReturn;
4267         }
4268
4269       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4270         {
4271           werror (E_PLUS_INVALID, "+=");
4272           goto errorTreeReturn;
4273         }
4274       RRVAL (tree) = 1;
4275       TETYPE (tree) = getSpec (TTYPE (tree) =
4276                                computeType (LTYPE (tree),
4277                                             RTYPE (tree),
4278                                             RESULT_TYPE_NOPROM,
4279                                             tree->opval.op));
4280
4281       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4282         werror (E_CODE_WRITE, "+=");
4283
4284       if (LRVAL (tree))
4285         {
4286           werror (E_LVALUE_REQUIRED, "+=");
4287           goto errorTreeReturn;
4288         }
4289
4290       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4291       tree->opval.op = '=';
4292
4293       return tree;
4294 #endif
4295
4296       /*------------------------------------------------------------------*/
4297       /*----------------------------*/
4298       /*      straight assignemnt   */
4299       /*----------------------------*/
4300     case '=':
4301       /* cannot be an aggregate */
4302       if (IS_AGGREGATE (LTYPE (tree)))
4303         {
4304           werror (E_AGGR_ASSIGN);
4305           goto errorTreeReturn;
4306         }
4307
4308       /* they should either match or be castable */
4309       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4310         {
4311           werror (E_TYPE_MISMATCH, "assignment", " ");
4312           printFromToType(RTYPE(tree),LTYPE(tree));
4313         }
4314
4315       /* if the left side of the tree is of type void
4316          then report error */
4317       if (IS_VOID (LTYPE (tree)))
4318         {
4319           werror (E_CAST_ZERO);
4320           printFromToType(RTYPE(tree), LTYPE(tree));
4321         }
4322
4323       TETYPE (tree) = getSpec (TTYPE (tree) =
4324                                LTYPE (tree));
4325       RRVAL (tree) = 1;
4326       LLVAL (tree) = 1;
4327       if (!tree->initMode ) {
4328         if (IS_CONSTANT(LTYPE(tree)))
4329           werror (E_CODE_WRITE, "=");
4330       }
4331       if (LRVAL (tree))
4332         {
4333           werror (E_LVALUE_REQUIRED, "=");
4334           goto errorTreeReturn;
4335         }
4336
4337       return tree;
4338
4339       /*------------------------------------------------------------------*/
4340       /*----------------------------*/
4341       /*      comma operator        */
4342       /*----------------------------*/
4343     case ',':
4344       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4345       return tree;
4346
4347       /*------------------------------------------------------------------*/
4348       /*----------------------------*/
4349       /*       function call        */
4350       /*----------------------------*/
4351     case CALL:
4352
4353       /* undo any explicit pointer derefernce; PCALL will handle it instead */
4354       if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4355         {
4356           if (tree->left->opval.op == '*' && !tree->left->right)
4357             tree->left = tree->left->left;
4358         }
4359
4360       /* require a function or pointer to function */
4361       if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4362         {
4363           werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4364           goto errorTreeReturn;
4365         }
4366
4367       /* if there are parms, make sure that
4368          parms are decorate / process / reverse only once */
4369       if (!tree->right ||
4370           !tree->right->decorated)
4371         {
4372           sym_link *functype;
4373           parmNumber = 1;
4374
4375           if (IS_FUNCPTR (LTYPE (tree)))
4376             {
4377               functype = LTYPE (tree)->next;
4378               processFuncPtrArgs (functype);
4379             }
4380           else
4381             functype = LTYPE (tree);
4382
4383           if (processParms (tree->left, FUNC_ARGS(functype),
4384                             &tree->right, &parmNumber, TRUE))
4385             {
4386               goto errorTreeReturn;
4387             }
4388
4389           if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4390              !IFFUNC_ISBUILTIN(functype))
4391             {
4392               reverseParms (tree->right);
4393             }
4394
4395            TTYPE (tree) = functype->next;
4396            TETYPE (tree) = getSpec (TTYPE (tree));
4397         }
4398       return tree;
4399
4400       /*------------------------------------------------------------------*/
4401       /*----------------------------*/
4402       /*     return statement       */
4403       /*----------------------------*/
4404     case RETURN:
4405       if (!tree->right)
4406         goto voidcheck;
4407
4408       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4409         {
4410           werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4411           printFromToType (RTYPE(tree), currFunc->type->next);
4412           goto errorTreeReturn;
4413         }
4414
4415       if (IS_VOID (currFunc->type->next)
4416           && tree->right &&
4417           !IS_VOID (RTYPE (tree)))
4418         {
4419           werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4420           goto errorTreeReturn;
4421         }
4422
4423       /* if there is going to be a casting required then add it */
4424       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4425         {
4426           tree->right =
4427             decorateType (newNode (CAST,
4428                           newAst_LINK (copyLinkChain (currFunc->type->next)),
4429                                         tree->right),
4430                           RESULT_TYPE_NONE);
4431         }
4432
4433       RRVAL (tree) = 1;
4434       return tree;
4435
4436     voidcheck:
4437
4438       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4439         {
4440           werror (W_VOID_FUNC, currFunc->name);
4441           goto errorTreeReturn;
4442         }
4443
4444       TTYPE (tree) = TETYPE (tree) = NULL;
4445       return tree;
4446
4447       /*------------------------------------------------------------------*/
4448       /*----------------------------*/
4449       /*     switch statement       */
4450       /*----------------------------*/
4451     case SWITCH:
4452       /* the switch value must be an integer */
4453       if (!IS_INTEGRAL (LTYPE (tree)))
4454         {
4455           werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4456           goto errorTreeReturn;
4457         }
4458       LRVAL (tree) = 1;
4459       TTYPE (tree) = TETYPE (tree) = NULL;
4460       return tree;
4461
4462       /*------------------------------------------------------------------*/
4463       /*----------------------------*/
4464       /* ifx Statement              */
4465       /*----------------------------*/
4466     case IFX:
4467       tree->left = backPatchLabels (tree->left,
4468                                     tree->trueLabel,
4469                                     tree->falseLabel);
4470       TTYPE (tree) = TETYPE (tree) = NULL;
4471       return tree;
4472
4473       /*------------------------------------------------------------------*/
4474       /*----------------------------*/
4475       /* for Statement              */
4476       /*----------------------------*/
4477     case FOR:
4478
4479       decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4480       decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4481       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4482
4483       /* if the for loop is reversible then
4484          reverse it otherwise do what we normally
4485          do */
4486       {
4487         symbol *sym;
4488         ast *init, *end;
4489
4490         if (isLoopReversible (tree, &sym, &init, &end))
4491           return reverseLoop (tree, sym, init, end);
4492         else
4493           return decorateType (createFor (AST_FOR (tree, trueLabel),
4494                                           AST_FOR (tree, continueLabel),
4495                                           AST_FOR (tree, falseLabel),
4496                                           AST_FOR (tree, condLabel),
4497                                           AST_FOR (tree, initExpr),
4498                                           AST_FOR (tree, condExpr),
4499                                           AST_FOR (tree, loopExpr),
4500                                           tree->left), RESULT_TYPE_NONE);
4501       }
4502     case PARAM:
4503       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4504               "node PARAM shouldn't be processed here");
4505               /* but in processParams() */
4506       return tree;
4507     default:
4508       TTYPE (tree) = TETYPE (tree) = NULL;
4509       return tree;
4510     }
4511
4512   /* some error found this tree will be killed */
4513 errorTreeReturn:
4514   TTYPE (tree) = TETYPE (tree) = newCharLink ();
4515   tree->opval.op = NULLOP;
4516   tree->isError = 1;
4517
4518   return tree;
4519 }
4520
4521 /*-----------------------------------------------------------------*/
4522 /* sizeofOp - processes size of operation                          */
4523 /*-----------------------------------------------------------------*/
4524 value *
4525 sizeofOp (sym_link * type)
4526 {
4527   char buff[10];
4528   int size;
4529
4530   /* make sure the type is complete and sane */
4531   checkTypeSanity(type, "(sizeof)");
4532
4533   /* get the size and convert it to character  */
4534   SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4535   if (!size && !IS_VOID(type))
4536     werror (E_SIZEOF_INCOMPLETE_TYPE);
4537
4538   /* now convert into value  */
4539   return constVal (buff);
4540 }
4541
4542
4543 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4544 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
4545 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4546 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4547 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4548 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
4549 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
4550
4551 /*-----------------------------------------------------------------*/
4552 /* backPatchLabels - change and or not operators to flow control    */
4553 /*-----------------------------------------------------------------*/
4554 static ast *
4555 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4556 {
4557
4558   if (!tree)
4559     return NULL;
4560
4561   if (!(IS_ANDORNOT (tree)))
4562     return tree;
4563
4564   /* if this an and */
4565   if (IS_AND (tree))
4566     {
4567       static int localLbl = 0;
4568       symbol *localLabel;
4569
4570       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4571       localLabel = newSymbol (buffer, NestLevel);
4572
4573       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4574
4575       /* if left is already a IFX then just change the if true label in that */
4576       if (!IS_IFX (tree->left))
4577         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4578
4579       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4580       /* right is a IFX then just join */
4581       if (IS_IFX (tree->right))
4582         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4583
4584       tree->right = createLabel (localLabel, tree->right);
4585       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4586
4587       return newNode (NULLOP, tree->left, tree->right);
4588     }
4589
4590   /* if this is an or operation */
4591   if (IS_OR (tree))
4592     {
4593       static int localLbl = 0;
4594       symbol *localLabel;
4595
4596       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4597       localLabel = newSymbol (buffer, NestLevel);
4598
4599       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4600
4601       /* if left is already a IFX then just change the if true label in that */
4602       if (!IS_IFX (tree->left))
4603         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4604
4605       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4606       /* right is a IFX then just join */
4607       if (IS_IFX (tree->right))
4608         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4609
4610       tree->right = createLabel (localLabel, tree->right);
4611       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4612
4613       return newNode (NULLOP, tree->left, tree->right);
4614     }
4615
4616   /* change not */
4617   if (IS_NOT (tree))
4618     {
4619       /* call with exchanged labels */
4620       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4621
4622       /* if left isn't already a IFX */
4623       if (!IS_IFX (tree->left))
4624         {
4625           tree->left = newNode (IFX, tree->left, NULL);
4626           tree->left->trueLabel = falseLabel;
4627           tree->left->falseLabel = trueLabel;
4628         }
4629       return tree->left;
4630      }
4631
4632   if (IS_IFX (tree))
4633     {
4634       tree->trueLabel = trueLabel;
4635       tree->falseLabel = falseLabel;
4636     }
4637
4638   return tree;
4639 }
4640
4641
4642 /*-----------------------------------------------------------------*/
4643 /* createBlock - create expression tree for block                  */
4644 /*-----------------------------------------------------------------*/
4645 ast *
4646 createBlock (symbol * decl, ast * body)
4647 {
4648   ast *ex;
4649
4650   /* if the block has nothing */
4651   if (!body && !decl)
4652     return NULL;
4653
4654   ex = newNode (BLOCK, NULL, body);
4655   ex->values.sym = decl;
4656
4657   ex->level++;
4658   ex->lineno = 0;
4659   return ex;
4660 }
4661
4662 /*-----------------------------------------------------------------*/
4663 /* createLabel - creates the expression tree for labels            */
4664 /*-----------------------------------------------------------------*/
4665 ast *
4666 createLabel (symbol * label, ast * stmnt)
4667 {
4668   symbol *csym;
4669   char name[SDCC_NAME_MAX + 1];
4670   ast *rValue;
4671
4672   /* must create fresh symbol if the symbol name  */
4673   /* exists in the symbol table, since there can  */
4674   /* be a variable with the same name as the labl */
4675   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4676       (csym->level == label->level))
4677     label = newSymbol (label->name, label->level);
4678
4679   /* change the name before putting it in add _ */
4680   SNPRINTF(name, sizeof(name), "%s", label->name);
4681
4682   /* put the label in the LabelSymbol table    */
4683   /* but first check if a label of the same    */
4684   /* name exists                               */
4685   if ((csym = findSym (LabelTab, NULL, name)))
4686     werror (E_DUPLICATE_LABEL, label->name);
4687   else
4688     addSym (LabelTab, label, name, label->level, 0, 0);
4689
4690   label->isitmp = 1;
4691   label->islbl = 1;
4692   label->key = labelKey++;
4693   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4694   rValue->lineno = 0;
4695
4696   return rValue;
4697 }
4698
4699 /*-----------------------------------------------------------------*/
4700 /* createCase - generates the parsetree for a case statement       */
4701 /*-----------------------------------------------------------------*/
4702 ast *
4703 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4704 {
4705   char caseLbl[SDCC_NAME_MAX + 1];
4706   ast *rexpr;
4707   value *val;
4708
4709   /* if the switch statement does not exist */
4710   /* then case is out of context            */
4711   if (!swStat)
4712     {
4713       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4714       return NULL;
4715     }
4716
4717   caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4718   /* if not a constant then error  */
4719   if (!IS_LITERAL (caseVal->ftype))
4720     {
4721       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4722       return NULL;
4723     }
4724
4725   /* if not a integer than error */
4726   if (!IS_INTEGRAL (caseVal->ftype))
4727     {
4728       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4729       return NULL;
4730     }
4731
4732   /* find the end of the switch values chain   */
4733   if (!(val = swStat->values.switchVals.swVals))
4734     swStat->values.switchVals.swVals = caseVal->opval.val;
4735   else
4736     {
4737       /* also order the cases according to value */
4738       value *pval = NULL;
4739       int cVal = (int) floatFromVal (caseVal->opval.val);
4740       while (val && (int) floatFromVal (val) < cVal)
4741         {
4742           pval = val;
4743           val = val->next;
4744         }
4745
4746       /* if we reached the end then */
4747       if (!val)
4748         {
4749           pval->next = caseVal->opval.val;
4750         }
4751       else if ((int) floatFromVal (val) == cVal)
4752         {
4753           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4754                     "case");
4755           return NULL;
4756         }
4757       else
4758         {
4759           /* we found a value greater than */
4760           /* the current value we must add this */
4761           /* before the value */
4762           caseVal->opval.val->next = val;
4763
4764           /* if this was the first in chain */
4765           if (swStat->values.switchVals.swVals == val)
4766             swStat->values.switchVals.swVals =
4767               caseVal->opval.val;
4768           else
4769             pval->next = caseVal->opval.val;
4770         }
4771
4772     }
4773
4774   /* create the case label   */
4775   SNPRINTF(caseLbl, sizeof(caseLbl),
4776            "_case_%d_%d",
4777            swStat->values.switchVals.swNum,
4778            (int) floatFromVal (caseVal->opval.val));
4779
4780   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4781   rexpr->lineno = 0;
4782   return rexpr;
4783 }
4784
4785 /*-----------------------------------------------------------------*/
4786 /* createDefault - creates the parse tree for the default statement */
4787 /*-----------------------------------------------------------------*/
4788 ast *
4789 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4790 {
4791   char defLbl[SDCC_NAME_MAX + 1];
4792
4793   /* if the switch statement does not exist */
4794   /* then case is out of context            */
4795   if (!swStat)
4796     {
4797       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4798       return NULL;
4799     }
4800
4801   if (swStat->values.switchVals.swDefault)
4802     {
4803       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4804                 "default");
4805       return NULL;
4806     }
4807
4808   /* turn on the default flag   */
4809   swStat->values.switchVals.swDefault = 1;
4810
4811   /* create the label  */
4812   SNPRINTF (defLbl, sizeof(defLbl),
4813             "_default_%d", swStat->values.switchVals.swNum);
4814   return createLabel (newSymbol (defLbl, 0), stmnt);
4815 }
4816
4817 /*-----------------------------------------------------------------*/
4818 /* createIf - creates the parsetree for the if statement           */
4819 /*-----------------------------------------------------------------*/
4820 ast *
4821 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4822 {
4823   static int Lblnum = 0;
4824   ast *ifTree;
4825   symbol *ifTrue, *ifFalse, *ifEnd;
4826
4827   /* if neither exists */
4828   if (!elseBody && !ifBody) {
4829     // if there are no side effects (i++, j() etc)
4830     if (!hasSEFcalls(condAst)) {
4831       return condAst;
4832     }
4833   }
4834
4835   /* create the labels */
4836   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4837   ifFalse = newSymbol (buffer, NestLevel);
4838   /* if no else body then end == false */
4839   if (!elseBody)
4840     ifEnd = ifFalse;
4841   else
4842     {
4843       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4844       ifEnd = newSymbol (buffer, NestLevel);
4845     }
4846
4847   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4848   ifTrue = newSymbol (buffer, NestLevel);
4849
4850   Lblnum++;
4851
4852   /* attach the ifTrue label to the top of it body */
4853   ifBody = createLabel (ifTrue, ifBody);
4854   /* attach a goto end to the ifBody if else is present */
4855   if (elseBody)
4856     {
4857       ifBody = newNode (NULLOP, ifBody,
4858                         newNode (GOTO,
4859                                  newAst_VALUE (symbolVal (ifEnd)),
4860                                  NULL));
4861       /* put the elseLabel on the else body */
4862       elseBody = createLabel (ifFalse, elseBody);
4863       /* out the end at the end of the body */
4864       elseBody = newNode (NULLOP,
4865                           elseBody,
4866                           createLabel (ifEnd, NULL));
4867     }
4868   else
4869     {
4870       ifBody = newNode (NULLOP, ifBody,
4871                         createLabel (ifFalse, NULL));
4872     }
4873   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4874   if (IS_IFX (condAst))
4875     ifTree = condAst;
4876   else
4877     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4878
4879   return newNode (NULLOP, ifTree,
4880                   newNode (NULLOP, ifBody, elseBody));
4881
4882 }
4883
4884 /*-----------------------------------------------------------------*/
4885 /* createDo - creates parse tree for do                            */
4886 /*        _dobody_n:                                               */
4887 /*            statements                                           */
4888 /*        _docontinue_n:                                           */
4889 /*            condition_expression +-> trueLabel -> _dobody_n      */
4890 /*                                 |                               */
4891 /*                                 +-> falseLabel-> _dobreak_n     */
4892 /*        _dobreak_n:                                              */
4893 /*-----------------------------------------------------------------*/
4894 ast *
4895 createDo (symbol * trueLabel, symbol * continueLabel,
4896           symbol * falseLabel, ast * condAst, ast * doBody)
4897 {
4898   ast *doTree;
4899
4900
4901   /* if the body does not exist then it is simple */
4902   if (!doBody)
4903     {
4904       condAst = backPatchLabels (condAst, continueLabel, NULL);
4905       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4906                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4907       doTree->trueLabel = continueLabel;
4908       doTree->falseLabel = NULL;
4909       return doTree;
4910     }
4911
4912   /* otherwise we have a body */
4913   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4914
4915   /* attach the body label to the top */
4916   doBody = createLabel (trueLabel, doBody);
4917   /* attach the continue label to end of body */
4918   doBody = newNode (NULLOP, doBody,
4919                     createLabel (continueLabel, NULL));
4920
4921   /* now put the break label at the end */
4922   if (IS_IFX (condAst))
4923     doTree = condAst;
4924   else
4925     doTree = newIfxNode (condAst, trueLabel, falseLabel);
4926
4927   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4928
4929   /* putting it together */
4930   return newNode (NULLOP, doBody, doTree);
4931 }
4932
4933 /*-----------------------------------------------------------------*/
4934 /* createFor - creates parse tree for 'for' statement              */
4935 /*        initExpr                                                 */
4936 /*   _forcond_n:                                                   */
4937 /*        condExpr  +-> trueLabel -> _forbody_n                    */
4938 /*                  |                                              */
4939 /*                  +-> falseLabel-> _forbreak_n                   */
4940 /*   _forbody_n:                                                   */
4941 /*        statements                                               */
4942 /*   _forcontinue_n:                                               */
4943 /*        loopExpr                                                 */
4944 /*        goto _forcond_n ;                                        */
4945 /*   _forbreak_n:                                                  */
4946 /*-----------------------------------------------------------------*/
4947 ast *
4948 createFor (symbol * trueLabel, symbol * continueLabel,
4949            symbol * falseLabel, symbol * condLabel,
4950            ast * initExpr, ast * condExpr, ast * loopExpr,
4951            ast * forBody)
4952 {
4953   ast *forTree;
4954
4955   /* if loopexpression not present then we can generate it */
4956   /* the same way as a while */
4957   if (!loopExpr)
4958     return newNode (NULLOP, initExpr,
4959                     createWhile (trueLabel, continueLabel,
4960                                  falseLabel, condExpr, forBody));
4961   /* vanilla for statement */
4962   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4963
4964   if (condExpr && !IS_IFX (condExpr))
4965     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4966
4967
4968   /* attach condition label to condition */
4969   condExpr = createLabel (condLabel, condExpr);
4970
4971   /* attach body label to body */
4972   forBody = createLabel (trueLabel, forBody);
4973
4974   /* attach continue to forLoop expression & attach */
4975   /* goto the forcond @ and of loopExpression       */
4976   loopExpr = createLabel (continueLabel,
4977                           newNode (NULLOP,
4978                                    loopExpr,
4979                                    newNode (GOTO,
4980                                        newAst_VALUE (symbolVal (condLabel)),
4981                                             NULL)));
4982   /* now start putting them together */
4983   forTree = newNode (NULLOP, initExpr, condExpr);
4984   forTree = newNode (NULLOP, forTree, forBody);
4985   forTree = newNode (NULLOP, forTree, loopExpr);
4986   /* finally add the break label */
4987   forTree = newNode (NULLOP, forTree,
4988                      createLabel (falseLabel, NULL));
4989   return forTree;
4990 }
4991
4992 /*-----------------------------------------------------------------*/
4993 /* createWhile - creates parse tree for while statement            */
4994 /*               the while statement will be created as follows    */
4995 /*                                                                 */
4996 /*      _while_continue_n:                                         */
4997 /*            condition_expression +-> trueLabel -> _while_boby_n  */
4998 /*                                 |                               */
4999 /*                                 +-> falseLabel -> _while_break_n */
5000 /*      _while_body_n:                                             */
5001 /*            statements                                           */
5002 /*            goto _while_continue_n                               */
5003 /*      _while_break_n:                                            */
5004 /*-----------------------------------------------------------------*/
5005 ast *
5006 createWhile (symbol * trueLabel, symbol * continueLabel,
5007              symbol * falseLabel, ast * condExpr, ast * whileBody)
5008 {
5009   ast *whileTree;
5010
5011   /* put the continue label */
5012   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5013   condExpr = createLabel (continueLabel, condExpr);
5014   condExpr->lineno = 0;
5015
5016   /* put the body label in front of the body */
5017   whileBody = createLabel (trueLabel, whileBody);
5018   whileBody->lineno = 0;
5019   /* put a jump to continue at the end of the body */
5020   /* and put break label at the end of the body */
5021   whileBody = newNode (NULLOP,
5022                        whileBody,
5023                        newNode (GOTO,
5024                                 newAst_VALUE (symbolVal (continueLabel)),
5025                                 createLabel (falseLabel, NULL)));
5026
5027   /* put it all together */
5028   if (IS_IFX (condExpr))
5029     whileTree = condExpr;
5030   else
5031     {
5032       whileTree = newNode (IFX, condExpr, NULL);
5033       /* put the true & false labels in place */
5034       whileTree->trueLabel = trueLabel;
5035       whileTree->falseLabel = falseLabel;
5036     }
5037
5038   return newNode (NULLOP, whileTree, whileBody);
5039 }
5040
5041 /*-----------------------------------------------------------------*/
5042 /* isShiftRightLitVal _BitAndLitVal - helper function              */
5043 /*-----------------------------------------------------------------*/
5044 static ast *
5045 isShiftRightLitVal_BitAndLitVal (ast * tree)
5046 {
5047   /* if this is not a bit and */
5048   if (!IS_BITAND (tree))
5049     return NULL;
5050
5051   /* will look for tree of the form
5052      ( expr >> litval2) & litval1 */
5053   if (!IS_AST_LIT_VALUE (tree->right))
5054     return NULL;
5055
5056   if (!IS_RIGHT_OP (tree->left))
5057     return NULL;
5058
5059   if (!IS_AST_LIT_VALUE (tree->left->right))
5060     return NULL;
5061
5062   return tree->left->left;
5063 }
5064
5065 /*-----------------------------------------------------------------*/
5066 /* isBitAndPowOf2 - helper function                                */
5067 /*-----------------------------------------------------------------*/
5068 static int
5069 isBitAndPow2 (ast * tree)
5070 {
5071   /* if this is not a bit and */
5072   if (!IS_BITAND (tree))
5073     return -1;
5074
5075   /* will look for tree of the form
5076      ( expr & (1 << litval) */
5077   if (!IS_AST_LIT_VALUE (tree->right))
5078     return -1;
5079
5080   return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5081 }
5082
5083 /*-----------------------------------------------------------------*/
5084 /* optimizeGetHbit - get highest order bit of the expression       */
5085 /*-----------------------------------------------------------------*/
5086 ast *
5087 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5088 {
5089   int i, j;
5090   ast * expr;
5091
5092   expr = isShiftRightLitVal_BitAndLitVal(tree);
5093   if (expr)
5094     {
5095       if ((AST_LIT_VALUE (tree->right) != 1) ||
5096           ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5097           (j = (getSize (TTYPE (expr)) * 8 - 1))))
5098         expr = NULL;
5099     }
5100   if (!expr && (resultType == RESULT_TYPE_BIT))
5101     {
5102       expr = tree->left;
5103       if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5104         expr = NULL;
5105     }
5106   if (!expr)
5107     return tree;
5108
5109   /* make sure the port supports GETHBIT */
5110   if (port->hasExtBitOp
5111       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5112     return tree;
5113
5114   return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5115 }
5116
5117 /*-----------------------------------------------------------------*/
5118 /* optimizeGetAbit - get a single bit of the expression            */
5119 /*-----------------------------------------------------------------*/
5120 ast *
5121 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5122 {
5123   ast * expr;
5124   ast * count = NULL;
5125
5126   expr = isShiftRightLitVal_BitAndLitVal(tree);
5127   if (expr)
5128     {
5129   if (AST_LIT_VALUE (tree->right) != 1)
5130         expr = NULL;
5131       count = tree->left->right;
5132     }
5133   if (!expr && (resultType == RESULT_TYPE_BIT))
5134     {
5135       int p2 = isBitAndPow2 (tree);
5136       if (p2 >= 0)
5137         {
5138           expr = tree->left;
5139           count = newAst_VALUE (valueFromLit (p2));
5140         }
5141     }
5142   if (!expr)
5143     return tree;
5144
5145   /* make sure the port supports GETABIT */
5146   if (port->hasExtBitOp
5147       && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5148     return tree;
5149
5150   return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5151
5152 }
5153
5154 /*-----------------------------------------------------------------*/
5155 /* optimizeGetByte - get a byte of the expression                  */
5156 /*-----------------------------------------------------------------*/
5157 ast *
5158 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5159 {
5160   unsigned int i = 0;
5161   ast * expr;
5162   ast * count = NULL;
5163
5164   expr = isShiftRightLitVal_BitAndLitVal(tree);
5165   if (expr)
5166     {
5167       i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5168       count = tree->left->right;
5169       if (AST_LIT_VALUE (tree->right) != 0xFF)
5170         expr = NULL;
5171     }
5172   if (!expr && resultType == RESULT_TYPE_CHAR)
5173     {
5174       /* if this is a right shift over a multiple of 8 */
5175       if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5176         {
5177           i = (unsigned int) AST_LIT_VALUE (tree->right);
5178           count = tree->right;
5179             expr = tree->left;
5180         }
5181     }
5182   if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5183     return tree;
5184
5185   /* make sure the port supports GETBYTE */
5186   if (port->hasExtBitOp
5187       && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5188     return tree;
5189
5190   return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5191 }
5192
5193 /*-----------------------------------------------------------------*/
5194 /* optimizeGetWord - get two bytes of the expression               */
5195 /*-----------------------------------------------------------------*/
5196 ast *
5197 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5198 {
5199   unsigned int i = 0;
5200   ast * expr;
5201   ast * count = NULL;
5202
5203   expr = isShiftRightLitVal_BitAndLitVal(tree);
5204   if (expr)
5205     {
5206       i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5207       count = tree->left->right;
5208       if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5209         expr = NULL;
5210     }
5211   if (!expr && resultType == RESULT_TYPE_INT)
5212     {
5213       /* if this is a right shift over a multiple of 8 */
5214       if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5215         {
5216           i = (unsigned int) AST_LIT_VALUE (tree->right);
5217           count = tree->right;
5218             expr = tree->left;
5219         }
5220     }
5221   if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5222     return tree;
5223
5224   /* make sure the port supports GETWORD */
5225   if (port->hasExtBitOp
5226       && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5227     return tree;
5228
5229   return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5230 }
5231
5232 /*-----------------------------------------------------------------*/
5233 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
5234 /*-----------------------------------------------------------------*/
5235 ast *
5236 optimizeRRCRLC (ast * root)
5237 {
5238   /* will look for trees of the form
5239      (?expr << 1) | (?expr >> 7) or
5240      (?expr >> 7) | (?expr << 1) will make that
5241      into a RLC : operation ..
5242      Will also look for
5243      (?expr >> 1) | (?expr << 7) or
5244      (?expr << 7) | (?expr >> 1) will make that
5245      into a RRC operation
5246      note : by 7 I mean (number of bits required to hold the
5247      variable -1 ) */
5248   /* if the root operation is not a | operation then not */
5249   if (!IS_BITOR (root))
5250     return root;
5251
5252   /* I have to think of a better way to match patterns this sucks */
5253   /* that aside let's start looking for the first case : I use a
5254      negative check a lot to improve the efficiency */
5255   /* (?expr << 1) | (?expr >> 7) */
5256   if (IS_LEFT_OP (root->left) &&
5257       IS_RIGHT_OP (root->right))
5258     {
5259
5260       if (!SPEC_USIGN (TETYPE (root->left->left)))
5261         return root;
5262
5263       if (!IS_AST_LIT_VALUE (root->left->right) ||
5264           !IS_AST_LIT_VALUE (root->right->right))
5265         goto tryNext0;
5266
5267       /* make sure it is the same expression */
5268       if (!isAstEqual (root->left->left,
5269                        root->right->left))
5270         goto tryNext0;
5271
5272       if (AST_LIT_VALUE (root->left->right) != 1)
5273         goto tryNext0;
5274
5275       if (AST_LIT_VALUE (root->right->right) !=
5276           (getSize (TTYPE (root->left->left)) * 8 - 1))
5277         goto tryNext0;
5278
5279       /* make sure the port supports RLC */
5280       if (port->hasExtBitOp
5281           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5282         return root;
5283
5284       /* whew got the first case : create the AST */
5285       return newNode (RLC, root->left->left, NULL);
5286     }
5287
5288 tryNext0:
5289   /* check for second case */
5290   /* (?expr >> 7) | (?expr << 1) */
5291   if (IS_LEFT_OP (root->right) &&
5292       IS_RIGHT_OP (root->left))
5293     {
5294
5295       if (!SPEC_USIGN (TETYPE (root->left->left)))
5296         return root;
5297
5298       if (!IS_AST_LIT_VALUE (root->left->right) ||
5299           !IS_AST_LIT_VALUE (root->right->right))
5300         goto tryNext1;
5301
5302       /* make sure it is the same symbol */
5303       if (!isAstEqual (root->left->left,
5304                        root->right->left))
5305         goto tryNext1;
5306
5307       if (AST_LIT_VALUE (root->right->right) != 1)
5308         goto tryNext1;
5309
5310       if (AST_LIT_VALUE (root->left->right) !=
5311           (getSize (TTYPE (root->left->left)) * 8 - 1))
5312         goto tryNext1;
5313
5314       /* make sure the port supports RLC */
5315       if (port->hasExtBitOp
5316           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5317         return root;
5318
5319       /* whew got the first case : create the AST */
5320       return newNode (RLC, root->left->left, NULL);
5321
5322     }
5323
5324 tryNext1:
5325   /* third case for RRC */
5326   /*  (?symbol >> 1) | (?symbol << 7) */
5327   if (IS_LEFT_OP (root->right) &&
5328       IS_RIGHT_OP (root->left))
5329     {
5330
5331       if (!SPEC_USIGN (TETYPE (root->left->left)))
5332         return root;
5333
5334       if (!IS_AST_LIT_VALUE (root->left->right) ||
5335           !IS_AST_LIT_VALUE (root->right->right))
5336         goto tryNext2;
5337
5338       /* make sure it is the same symbol */
5339       if (!isAstEqual (root->left->left,
5340                        root->right->left))
5341         goto tryNext2;
5342
5343       if (AST_LIT_VALUE (root->left->right) != 1)
5344         goto tryNext2;
5345
5346       if (AST_LIT_VALUE (root->right->right) !=
5347           (getSize (TTYPE (root->left->left)) * 8 - 1))
5348         goto tryNext2;
5349
5350       /* make sure the port supports RRC */
5351       if (port->hasExtBitOp
5352           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5353         return root;
5354
5355       /* whew got the first case : create the AST */
5356       return newNode (RRC, root->left->left, NULL);
5357
5358     }
5359 tryNext2:
5360   /* fourth and last case for now */
5361   /* (?symbol << 7) | (?symbol >> 1) */
5362   if (IS_RIGHT_OP (root->right) &&
5363       IS_LEFT_OP (root->left))
5364     {
5365
5366       if (!SPEC_USIGN (TETYPE (root->left->left)))
5367         return root;
5368
5369       if (!IS_AST_LIT_VALUE (root->left->right) ||
5370           !IS_AST_LIT_VALUE (root->right->right))
5371         return root;
5372
5373       /* make sure it is the same symbol */
5374       if (!isAstEqual (root->left->left,
5375                        root->right->left))
5376         return root;
5377
5378       if (AST_LIT_VALUE (root->right->right) != 1)
5379         return root;
5380
5381       if (AST_LIT_VALUE (root->left->right) !=
5382           (getSize (TTYPE (root->left->left)) * 8 - 1))
5383         return root;
5384
5385       /* make sure the port supports RRC */
5386       if (port->hasExtBitOp
5387           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5388         return root;
5389
5390       /* whew got the first case : create the AST */
5391       return newNode (RRC, root->left->left, NULL);
5392
5393     }
5394
5395   /* not found return root */
5396   return root;
5397 }
5398
5399 /*-----------------------------------------------------------------*/
5400 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
5401 /*-----------------------------------------------------------------*/
5402 ast *
5403 optimizeSWAP (ast * root)
5404 {
5405   /* will look for trees of the form
5406      (?expr << 4) | (?expr >> 4) or
5407      (?expr >> 4) | (?expr << 4) will make that
5408      into a SWAP : operation ..
5409      note : by 4 I mean (number of bits required to hold the
5410      variable /2 ) */
5411   /* if the root operation is not a | operation then not */
5412   if (!IS_BITOR (root))
5413     return root;
5414
5415   /* (?expr << 4) | (?expr >> 4) */
5416   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5417       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5418     {
5419
5420       if (!SPEC_USIGN (TETYPE (root->left->left)))
5421         return root;
5422
5423       if (!IS_AST_LIT_VALUE (root->left->right) ||
5424           !IS_AST_LIT_VALUE (root->right->right))
5425         return root;
5426
5427       /* make sure it is the same expression */
5428       if (!isAstEqual (root->left->left,
5429                        root->right->left))
5430         return root;
5431
5432       if (AST_LIT_VALUE (root->left->right) !=
5433           (getSize (TTYPE (root->left->left)) * 4))
5434         return root;
5435
5436       if (AST_LIT_VALUE (root->right->right) !=
5437           (getSize (TTYPE (root->left->left)) * 4))
5438         return root;
5439
5440       /* make sure the port supports SWAP */
5441       if (port->hasExtBitOp
5442           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5443         return root;
5444
5445       /* found it : create the AST */
5446       return newNode (SWAP, root->left->left, NULL);
5447     }
5448
5449
5450   /* not found return root */
5451   return root;
5452 }
5453
5454 /*-----------------------------------------------------------------*/
5455 /* optimizeCompare - optimizes compares for bit variables          */
5456 /*-----------------------------------------------------------------*/
5457 static ast *
5458 optimizeCompare (ast * root)
5459 {
5460   ast *optExpr = NULL;
5461   value *vleft;
5462   value *vright;
5463   unsigned int litValue;
5464
5465   /* if nothing then return nothing */
5466   if (!root)
5467     return NULL;
5468
5469   /* if not a compare op then do leaves */
5470   if (!IS_COMPARE_OP (root))
5471     {
5472       root->left = optimizeCompare (root->left);
5473       root->right = optimizeCompare (root->right);
5474       return root;
5475     }
5476
5477   /* if left & right are the same then depending
5478      of the operation do */
5479   if (isAstEqual (root->left, root->right))
5480     {
5481       switch (root->opval.op)
5482         {
5483         case '>':
5484         case '<':
5485         case NE_OP:
5486           optExpr = newAst_VALUE (constVal ("0"));
5487           break;
5488         case GE_OP:
5489         case LE_OP:
5490         case EQ_OP:
5491           optExpr = newAst_VALUE (constVal ("1"));
5492           break;
5493         }
5494
5495       return decorateType (optExpr, RESULT_TYPE_NONE);
5496     }
5497
5498   vleft = (root->left->type == EX_VALUE ?
5499            root->left->opval.val : NULL);
5500
5501   vright = (root->right->type == EX_VALUE ?
5502             root->right->opval.val : NULL);
5503
5504   /* if left is a BITVAR in BITSPACE */
5505   /* and right is a LITERAL then opt- */
5506   /* imize else do nothing       */
5507   if (vleft && vright &&
5508       IS_BITVAR (vleft->etype) &&
5509       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5510       IS_LITERAL (vright->etype))
5511     {
5512
5513       /* if right side > 1 then comparison may never succeed */
5514       if ((litValue = (int) floatFromVal (vright)) > 1)
5515         {
5516           werror (W_BAD_COMPARE);
5517           goto noOptimize;
5518         }
5519
5520       if (litValue)
5521         {
5522           switch (root->opval.op)
5523             {
5524             case '>':           /* bit value greater than 1 cannot be */
5525               werror (W_BAD_COMPARE);
5526               goto noOptimize;
5527               break;
5528
5529             case '<':           /* bit value < 1 means 0 */
5530             case NE_OP:
5531               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5532               break;
5533
5534             case LE_OP: /* bit value <= 1 means no check */
5535               optExpr = newAst_VALUE (vright);
5536               break;
5537
5538             case GE_OP: /* bit value >= 1 means only check for = */
5539             case EQ_OP:
5540               optExpr = newAst_VALUE (vleft);
5541               break;
5542             }
5543         }
5544       else
5545         {                       /* literal is zero */
5546           switch (root->opval.op)
5547             {
5548             case '<':           /* bit value < 0 cannot be */
5549               werror (W_BAD_COMPARE);
5550               goto noOptimize;
5551               break;
5552
5553             case '>':           /* bit value > 0 means 1 */
5554             case NE_OP:
5555               optExpr = newAst_VALUE (vleft);
5556               break;
5557
5558             case LE_OP: /* bit value <= 0 means no check */
5559             case GE_OP: /* bit value >= 0 means no check */
5560               werror (W_BAD_COMPARE);
5561               goto noOptimize;
5562               break;
5563
5564             case EQ_OP: /* bit == 0 means ! of bit */
5565               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5566               break;
5567             }
5568         }
5569       return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5570     }                           /* end-of-if of BITVAR */
5571
5572 noOptimize:
5573   return root;
5574 }
5575 /*-----------------------------------------------------------------*/
5576 /* addSymToBlock : adds the symbol to the first block we find      */
5577 /*-----------------------------------------------------------------*/
5578 void
5579 addSymToBlock (symbol * sym, ast * tree)
5580 {
5581   /* reached end of tree or a leaf */
5582   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5583     return;
5584
5585   /* found a block */
5586   if (IS_AST_OP (tree) &&
5587       tree->opval.op == BLOCK)
5588     {
5589
5590       symbol *lsym = copySymbol (sym);
5591
5592       lsym->next = AST_VALUES (tree, sym);
5593       AST_VALUES (tree, sym) = lsym;
5594       return;
5595     }
5596
5597   addSymToBlock (sym, tree->left);
5598   addSymToBlock (sym, tree->right);
5599 }
5600
5601 /*-----------------------------------------------------------------*/
5602 /* processRegParms - do processing for register parameters         */
5603 /*-----------------------------------------------------------------*/
5604 static void
5605 processRegParms (value * args, ast * body)
5606 {
5607   while (args)
5608     {
5609       if (IS_REGPARM (args->etype))
5610         addSymToBlock (args->sym, body);
5611       args = args->next;
5612     }
5613 }
5614
5615 /*-----------------------------------------------------------------*/
5616 /* resetParmKey - resets the operandkeys for the symbols           */
5617 /*-----------------------------------------------------------------*/
5618 DEFSETFUNC (resetParmKey)
5619 {
5620   symbol *sym = item;
5621
5622   sym->key = 0;
5623   sym->defs = NULL;
5624   sym->uses = NULL;
5625   sym->remat = 0;
5626   return 1;
5627 }
5628
5629 /*-----------------------------------------------------------------*/
5630 /* createFunction - This is the key node that calls the iCode for  */
5631 /*                  generating the code for a function. Note code  */
5632 /*                  is generated function by function, later when  */
5633 /*                  add inter-procedural analysis this will change */
5634 /*-----------------------------------------------------------------*/
5635 ast *
5636 createFunction (symbol * name, ast * body)
5637 {
5638   ast *ex;
5639   symbol *csym;
5640   int stack = 0;
5641   sym_link *fetype;
5642   iCode *piCode = NULL;
5643
5644   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5645     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5646
5647   /* if check function return 0 then some problem */
5648   if (checkFunction (name, NULL) == 0)
5649     return NULL;
5650
5651   /* create a dummy block if none exists */
5652   if (!body)
5653     body = newNode (BLOCK, NULL, NULL);
5654
5655   noLineno++;
5656
5657   /* check if the function name already in the symbol table */
5658   if ((csym = findSym (SymbolTab, NULL, name->name)))
5659     {
5660       name = csym;
5661       /* special case for compiler defined functions
5662          we need to add the name to the publics list : this
5663          actually means we are now compiling the compiler
5664          support routine */
5665       if (name->cdef)
5666         {
5667           addSet (&publics, name);
5668         }
5669     }
5670   else
5671     {
5672       addSymChain (&name);
5673       allocVariables (name);
5674     }
5675   name->lastLine = mylineno;
5676   currFunc = name;
5677
5678   /* set the stack pointer */
5679   stackPtr  = -port->stack.direction * port->stack.call_overhead;
5680   xstackPtr = 0;
5681
5682   if (IFFUNC_ISISR (name->type))
5683     stackPtr -= port->stack.direction * port->stack.isr_overhead;
5684
5685   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5686     {
5687       if (options.useXstack)
5688         xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5689       else
5690         stackPtr  -= port->stack.direction * port->stack.reent_overhead;
5691     }
5692
5693   fetype = getSpec (name->type);        /* get the specifier for the function */
5694   /* if this is a reentrant function then */
5695   if (IFFUNC_ISREENT (name->type))
5696     reentrant++;
5697
5698   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
5699
5700   /* do processing for parameters that are passed in registers */
5701   processRegParms (FUNC_ARGS(name->type), body);
5702
5703   /* set the stack pointer */
5704   stackPtr = 0;
5705   xstackPtr = -1;
5706
5707   /* allocate & autoinit the block variables */
5708   processBlockVars (body, &stack, ALLOCATE);
5709
5710   /* save the stack information */
5711   if (options.useXstack)
5712     name->xstack = SPEC_STAK (fetype) = stack;
5713   else
5714     name->stack = SPEC_STAK (fetype) = stack;
5715
5716   /* name needs to be mangled */
5717   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5718
5719   body = resolveSymbols (body); /* resolve the symbols */
5720   body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5721
5722   ex = newAst_VALUE (symbolVal (name)); /* create name */
5723   ex = newNode (FUNCTION, ex, body);
5724   ex->values.args = FUNC_ARGS(name->type);
5725   ex->decorated=1;
5726   if (options.dump_tree) PA(ex);
5727   if (fatalError)
5728     {
5729       werror (E_FUNC_NO_CODE, name->name);
5730       goto skipall;
5731     }
5732
5733   /* create the node & generate intermediate code */
5734   GcurMemmap = code;
5735   codeOutFile = code->oFile;
5736   piCode = iCodeFromAst (ex);
5737
5738   if (fatalError)
5739     {
5740       werror (E_FUNC_NO_CODE, name->name);
5741       goto skipall;
5742     }
5743
5744   eBBlockFromiCode (piCode);
5745
5746   /* if there are any statics then do them */
5747   if (staticAutos)
5748     {
5749       GcurMemmap = statsg;
5750       codeOutFile = statsg->oFile;
5751       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5752       staticAutos = NULL;
5753     }
5754
5755 skipall:
5756
5757   /* dealloc the block variables */
5758   processBlockVars (body, &stack, DEALLOCATE);
5759   outputDebugStackSymbols();
5760   /* deallocate paramaters */
5761   deallocParms (FUNC_ARGS(name->type));
5762
5763   if (IFFUNC_ISREENT (name->type))
5764     reentrant--;
5765
5766   /* we are done freeup memory & cleanup */
5767   noLineno--;
5768   if (port->reset_labelKey) labelKey = 1;
5769   name->key = 0;
5770   FUNC_HASBODY(name->type) = 1;
5771   addSet (&operKeyReset, name);
5772   applyToSet (operKeyReset, resetParmKey);
5773
5774   if (options.debug)
5775     cdbStructBlock(1);
5776
5777   cleanUpLevel (LabelTab, 0);
5778   cleanUpBlock (StructTab, 1);
5779   cleanUpBlock (TypedefTab, 1);
5780
5781   xstack->syms = NULL;
5782   istack->syms = NULL;
5783   return NULL;
5784 }
5785
5786
5787 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5788 /*-----------------------------------------------------------------*/
5789 /* ast_print : prints the ast (for debugging purposes)             */
5790 /*-----------------------------------------------------------------*/
5791
5792 void ast_print (ast * tree, FILE *outfile, int indent)
5793 {
5794
5795         if (!tree) return ;
5796
5797         /* can print only decorated trees */
5798         if (!tree->decorated) return;
5799
5800         /* if any child is an error | this one is an error do nothing */
5801         if (tree->isError ||
5802             (tree->left && tree->left->isError) ||
5803             (tree->right && tree->right->isError)) {
5804                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5805         }
5806
5807
5808         /* print the line          */
5809         /* if not block & function */
5810         if (tree->type == EX_OP &&
5811             (tree->opval.op != FUNCTION &&
5812              tree->opval.op != BLOCK &&
5813              tree->opval.op != NULLOP)) {
5814         }
5815
5816         if (tree->opval.op == FUNCTION) {
5817                 int arg=0;
5818                 value *args=FUNC_ARGS(tree->left->opval.val->type);
5819                 fprintf(outfile,"FUNCTION (%s=%p) type (",
5820                         tree->left->opval.val->name, tree);
5821                 printTypeChain (tree->left->opval.val->type->next,outfile);
5822                 fprintf(outfile,") args (");
5823                 do {
5824                   if (arg) {
5825                     fprintf (outfile, ", ");
5826                   }
5827                   printTypeChain (args ? args->type : NULL, outfile);
5828                   arg++;
5829                   args= args ? args->next : NULL;
5830                 } while (args);
5831                 fprintf(outfile,")\n");
5832                 ast_print(tree->left,outfile,indent);
5833                 ast_print(tree->right,outfile,indent);
5834                 return ;
5835         }
5836         if (tree->opval.op == BLOCK) {
5837                 symbol *decls = tree->values.sym;
5838                 INDENT(indent,outfile);
5839                 fprintf(outfile,"{\n");
5840                 while (decls) {
5841                         INDENT(indent+2,outfile);
5842                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5843                                 decls->name, decls);
5844                         printTypeChain(decls->type,outfile);
5845                         fprintf(outfile,")\n");
5846
5847                         decls = decls->next;
5848                 }
5849                 ast_print(tree->right,outfile,indent+2);
5850                 INDENT(indent,outfile);
5851                 fprintf(outfile,"}\n");
5852                 return;
5853         }
5854         if (tree->opval.op == NULLOP) {
5855                 ast_print(tree->left,outfile,indent);
5856                 ast_print(tree->right,outfile,indent);
5857                 return ;
5858         }
5859         INDENT(indent,outfile);
5860
5861         /*------------------------------------------------------------------*/
5862         /*----------------------------*/
5863         /*   leaf has been reached    */
5864         /*----------------------------*/
5865         /* if this is of type value */
5866         /* just get the type        */
5867         if (tree->type == EX_VALUE) {
5868
5869                 if (IS_LITERAL (tree->opval.val->etype)) {
5870                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
5871                         if (SPEC_USIGN (tree->opval.val->etype))
5872                                 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5873                         else
5874                                 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5875                         fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5876                                                       floatFromVal(tree->opval.val));
5877                 } else if (tree->opval.val->sym) {
5878                         /* if the undefined flag is set then give error message */
5879                         if (tree->opval.val->sym->undefined) {
5880                                 fprintf(outfile,"UNDEFINED SYMBOL ");
5881                         } else {
5882                                 fprintf(outfile,"SYMBOL ");
5883                         }
5884                         fprintf(outfile,"(%s=%p)",
5885                                 tree->opval.val->sym->name,tree);
5886                 }
5887                 if (tree->ftype) {
5888                         fprintf(outfile," type (");
5889                         printTypeChain(tree->ftype,outfile);
5890                         fprintf(outfile,")\n");
5891                 } else {
5892                         fprintf(outfile,"\n");
5893                 }
5894                 return ;
5895         }
5896
5897         /* if type link for the case of cast */
5898         if (tree->type == EX_LINK) {
5899                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5900                 printTypeChain(tree->opval.lnk,outfile);
5901                 fprintf(outfile,")\n");
5902                 return ;
5903         }
5904
5905
5906         /* depending on type of operator do */
5907
5908         switch (tree->opval.op) {
5909                 /*------------------------------------------------------------------*/
5910                 /*----------------------------*/
5911                 /*        array node          */
5912                 /*----------------------------*/
5913         case '[':
5914                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5915                 printTypeChain(tree->ftype,outfile);
5916                 fprintf(outfile,")\n");
5917                 ast_print(tree->left,outfile,indent+2);
5918                 ast_print(tree->right,outfile,indent+2);
5919                 return;
5920
5921                 /*------------------------------------------------------------------*/
5922                 /*----------------------------*/
5923                 /*      struct/union          */
5924                 /*----------------------------*/
5925         case '.':
5926                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5927                 printTypeChain(tree->ftype,outfile);
5928                 fprintf(outfile,")\n");
5929                 ast_print(tree->left,outfile,indent+2);
5930                 ast_print(tree->right,outfile,indent+2);
5931                 return ;
5932
5933                 /*------------------------------------------------------------------*/
5934                 /*----------------------------*/
5935                 /*    struct/union pointer    */
5936                 /*----------------------------*/
5937         case PTR_OP:
5938                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5939                 printTypeChain(tree->ftype,outfile);
5940                 fprintf(outfile,")\n");
5941                 ast_print(tree->left,outfile,indent+2);
5942                 ast_print(tree->right,outfile,indent+2);
5943                 return ;
5944
5945                 /*------------------------------------------------------------------*/
5946                 /*----------------------------*/
5947                 /*  ++/-- operation           */
5948                 /*----------------------------*/
5949         case INC_OP:
5950                 if (tree->left)
5951                   fprintf(outfile,"post-");
5952                 else
5953                   fprintf(outfile,"pre-");
5954                 fprintf(outfile,"INC_OP (%p) type (",tree);
5955                 printTypeChain(tree->ftype,outfile);
5956                 fprintf(outfile,")\n");
5957                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5958                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5959                 return ;
5960
5961         case DEC_OP:
5962                 if (tree->left)
5963                   fprintf(outfile,"post-");
5964                 else
5965                   fprintf(outfile,"pre-");
5966                 fprintf(outfile,"DEC_OP (%p) type (",tree);
5967                 printTypeChain(tree->ftype,outfile);
5968                 fprintf(outfile,")\n");
5969                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5970                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5971                 return ;
5972
5973                 /*------------------------------------------------------------------*/
5974                 /*----------------------------*/
5975                 /*  bitwise and               */
5976                 /*----------------------------*/
5977         case '&':
5978                 if (tree->right) {
5979                         fprintf(outfile,"& (%p) type (",tree);
5980                         printTypeChain(tree->ftype,outfile);
5981                         fprintf(outfile,")\n");
5982                         ast_print(tree->left,outfile,indent+2);
5983                         ast_print(tree->right,outfile,indent+2);
5984                 } else {
5985                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5986                         printTypeChain(tree->ftype,outfile);
5987                         fprintf(outfile,")\n");
5988                         ast_print(tree->left,outfile,indent+2);
5989                         ast_print(tree->right,outfile,indent+2);
5990                 }
5991                 return ;
5992                 /*----------------------------*/
5993                 /*  bitwise or                */
5994                 /*----------------------------*/
5995         case '|':
5996                 fprintf(outfile,"OR (%p) type (",tree);
5997                 printTypeChain(tree->ftype,outfile);
5998                 fprintf(outfile,")\n");
5999                 ast_print(tree->left,outfile,indent+2);
6000                 ast_print(tree->right,outfile,indent+2);
6001                 return ;
6002                 /*------------------------------------------------------------------*/
6003                 /*----------------------------*/
6004                 /*  bitwise xor               */
6005                 /*----------------------------*/
6006         case '^':
6007                 fprintf(outfile,"XOR (%p) type (",tree);
6008                 printTypeChain(tree->ftype,outfile);
6009                 fprintf(outfile,")\n");
6010                 ast_print(tree->left,outfile,indent+2);
6011                 ast_print(tree->right,outfile,indent+2);
6012                 return ;
6013
6014                 /*------------------------------------------------------------------*/
6015                 /*----------------------------*/
6016                 /*  division                  */
6017                 /*----------------------------*/
6018         case '/':
6019                 fprintf(outfile,"DIV (%p) type (",tree);
6020                 printTypeChain(tree->ftype,outfile);
6021                 fprintf(outfile,")\n");
6022                 ast_print(tree->left,outfile,indent+2);
6023                 ast_print(tree->right,outfile,indent+2);
6024                 return ;
6025                 /*------------------------------------------------------------------*/
6026                 /*----------------------------*/
6027                 /*            modulus         */
6028                 /*----------------------------*/
6029         case '%':
6030                 fprintf(outfile,"MOD (%p) type (",tree);
6031                 printTypeChain(tree->ftype,outfile);
6032                 fprintf(outfile,")\n");
6033                 ast_print(tree->left,outfile,indent+2);
6034                 ast_print(tree->right,outfile,indent+2);
6035                 return ;
6036
6037                 /*------------------------------------------------------------------*/
6038                 /*----------------------------*/
6039                 /*  address dereference       */
6040                 /*----------------------------*/
6041         case '*':                       /* can be unary  : if right is null then unary operation */
6042                 if (!tree->right) {
6043                         fprintf(outfile,"DEREF (%p) type (",tree);
6044                         printTypeChain(tree->ftype,outfile);
6045                         fprintf(outfile,")\n");
6046                         ast_print(tree->left,outfile,indent+2);
6047                         return ;
6048                 }
6049                 /*------------------------------------------------------------------*/
6050                 /*----------------------------*/
6051                 /*      multiplication        */
6052                 /*----------------------------*/
6053                 fprintf(outfile,"MULT (%p) type (",tree);
6054                 printTypeChain(tree->ftype,outfile);
6055                 fprintf(outfile,")\n");
6056                 ast_print(tree->left,outfile,indent+2);
6057                 ast_print(tree->right,outfile,indent+2);
6058                 return ;
6059
6060
6061                 /*------------------------------------------------------------------*/
6062                 /*----------------------------*/
6063                 /*    unary '+' operator      */
6064                 /*----------------------------*/
6065         case '+':
6066                 /* if unary plus */
6067                 if (!tree->right) {
6068                         fprintf(outfile,"UPLUS (%p) type (",tree);
6069                         printTypeChain(tree->ftype,outfile);
6070                         fprintf(outfile,")\n");
6071                         ast_print(tree->left,outfile,indent+2);
6072                 } else {
6073                         /*------------------------------------------------------------------*/
6074                         /*----------------------------*/
6075                         /*      addition              */
6076                         /*----------------------------*/
6077                         fprintf(outfile,"ADD (%p) type (",tree);
6078                         printTypeChain(tree->ftype,outfile);
6079                         fprintf(outfile,")\n");
6080                         ast_print(tree->left,outfile,indent+2);
6081                         ast_print(tree->right,outfile,indent+2);
6082                 }
6083                 return;
6084                 /*------------------------------------------------------------------*/
6085                 /*----------------------------*/
6086                 /*      unary '-'             */
6087                 /*----------------------------*/
6088         case '-':                       /* can be unary   */
6089                 if (!tree->right) {
6090                         fprintf(outfile,"UMINUS (%p) type (",tree);
6091                         printTypeChain(tree->ftype,outfile);
6092                         fprintf(outfile,")\n");
6093                         ast_print(tree->left,outfile,indent+2);
6094                 } else {
6095                         /*------------------------------------------------------------------*/
6096                         /*----------------------------*/
6097                         /*      subtraction           */
6098                         /*----------------------------*/
6099                         fprintf(outfile,"SUB (%p) type (",tree);
6100                         printTypeChain(tree->ftype,outfile);
6101                         fprintf(outfile,")\n");
6102                         ast_print(tree->left,outfile,indent+2);
6103                         ast_print(tree->right,outfile,indent+2);
6104                 }
6105                 return;
6106                 /*------------------------------------------------------------------*/
6107                 /*----------------------------*/
6108                 /*    complement              */
6109                 /*----------------------------*/
6110         case '~':
6111                 fprintf(outfile,"COMPL (%p) type (",tree);
6112                 printTypeChain(tree->ftype,outfile);
6113                 fprintf(outfile,")\n");
6114                 ast_print(tree->left,outfile,indent+2);
6115                 return ;
6116                 /*------------------------------------------------------------------*/
6117                 /*----------------------------*/
6118                 /*           not              */
6119                 /*----------------------------*/
6120         case '!':
6121                 fprintf(outfile,"NOT (%p) type (",tree);
6122                 printTypeChain(tree->ftype,outfile);
6123                 fprintf(outfile,")\n");
6124                 ast_print(tree->left,outfile,indent+2);
6125                 return ;
6126                 /*------------------------------------------------------------------*/
6127                 /*----------------------------*/
6128                 /*           shift            */
6129                 /*----------------------------*/
6130         case RRC:
6131                 fprintf(outfile,"RRC (%p) type (",tree);
6132                 printTypeChain(tree->ftype,outfile);
6133                 fprintf(outfile,")\n");
6134                 ast_print(tree->left,outfile,indent+2);
6135                 return ;
6136
6137         case RLC:
6138                 fprintf(outfile,"RLC (%p) type (",tree);
6139                 printTypeChain(tree->ftype,outfile);
6140                 fprintf(outfile,")\n");
6141                 ast_print(tree->left,outfile,indent+2);
6142                 return ;
6143         case SWAP:
6144                 fprintf(outfile,"SWAP (%p) type (",tree);
6145                 printTypeChain(tree->ftype,outfile);
6146                 fprintf(outfile,")\n");
6147                 ast_print(tree->left,outfile,indent+2);
6148                 return ;
6149         case GETHBIT:
6150                 fprintf(outfile,"GETHBIT (%p) type (",tree);
6151                 printTypeChain(tree->ftype,outfile);
6152                 fprintf(outfile,")\n");
6153                 ast_print(tree->left,outfile,indent+2);
6154                 return ;
6155         case GETABIT:
6156                 fprintf(outfile,"GETABIT (%p) type (",tree);
6157                 printTypeChain(tree->ftype,outfile);
6158                 fprintf(outfile,")\n");
6159                 ast_print(tree->left,outfile,indent+2);
6160                 ast_print(tree->right,outfile,indent+2);
6161                 return ;
6162         case GETBYTE:
6163                 fprintf(outfile,"GETBYTE (%p) type (",tree);
6164                 printTypeChain(tree->ftype,outfile);
6165                 fprintf(outfile,")\n");
6166                 ast_print(tree->left,outfile,indent+2);
6167                 ast_print(tree->right,outfile,indent+2);
6168                 return ;
6169         case GETWORD:
6170                 fprintf(outfile,"GETWORD (%p) type (",tree);
6171                 printTypeChain(tree->ftype,outfile);
6172                 fprintf(outfile,")\n");
6173                 ast_print(tree->left,outfile,indent+2);
6174                 ast_print(tree->right,outfile,indent+2);
6175                 return ;
6176         case LEFT_OP:
6177                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6178                 printTypeChain(tree->ftype,outfile);
6179                 fprintf(outfile,")\n");
6180                 ast_print(tree->left,outfile,indent+2);
6181                 ast_print(tree->right,outfile,indent+2);
6182                 return ;
6183         case RIGHT_OP:
6184                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6185                 printTypeChain(tree->ftype,outfile);
6186                 fprintf(outfile,")\n");
6187                 ast_print(tree->left,outfile,indent+2);
6188                 ast_print(tree->right,outfile,indent+2);
6189                 return ;
6190                 /*------------------------------------------------------------------*/
6191                 /*----------------------------*/
6192                 /*         casting            */
6193                 /*----------------------------*/
6194         case CAST:                      /* change the type   */
6195                 fprintf(outfile,"CAST (%p) from type (",tree);
6196                 printTypeChain(tree->right->ftype,outfile);
6197                 fprintf(outfile,") to type (");
6198                 printTypeChain(tree->ftype,outfile);
6199                 fprintf(outfile,")\n");
6200                 ast_print(tree->right,outfile,indent+2);
6201                 return ;
6202
6203         case AND_OP:
6204                 fprintf(outfile,"ANDAND (%p) type (",tree);
6205                 printTypeChain(tree->ftype,outfile);
6206                 fprintf(outfile,")\n");
6207                 ast_print(tree->left,outfile,indent+2);
6208                 ast_print(tree->right,outfile,indent+2);
6209                 return ;
6210         case OR_OP:
6211                 fprintf(outfile,"OROR (%p) type (",tree);
6212                 printTypeChain(tree->ftype,outfile);
6213                 fprintf(outfile,")\n");
6214                 ast_print(tree->left,outfile,indent+2);
6215                 ast_print(tree->right,outfile,indent+2);
6216                 return ;
6217
6218                 /*------------------------------------------------------------------*/
6219                 /*----------------------------*/
6220                 /*     comparison operators   */
6221                 /*----------------------------*/
6222         case '>':
6223                 fprintf(outfile,"GT(>) (%p) type (",tree);
6224                 printTypeChain(tree->ftype,outfile);
6225                 fprintf(outfile,")\n");
6226                 ast_print(tree->left,outfile,indent+2);
6227                 ast_print(tree->right,outfile,indent+2);
6228                 return ;
6229         case '<':
6230                 fprintf(outfile,"LT(<) (%p) type (",tree);
6231                 printTypeChain(tree->ftype,outfile);
6232                 fprintf(outfile,")\n");
6233                 ast_print(tree->left,outfile,indent+2);
6234                 ast_print(tree->right,outfile,indent+2);
6235                 return ;
6236         case LE_OP:
6237                 fprintf(outfile,"LE(<=) (%p) type (",tree);
6238                 printTypeChain(tree->ftype,outfile);
6239                 fprintf(outfile,")\n");
6240                 ast_print(tree->left,outfile,indent+2);
6241                 ast_print(tree->right,outfile,indent+2);
6242                 return ;
6243         case GE_OP:
6244                 fprintf(outfile,"GE(>=) (%p) type (",tree);
6245                 printTypeChain(tree->ftype,outfile);
6246                 fprintf(outfile,")\n");
6247                 ast_print(tree->left,outfile,indent+2);
6248                 ast_print(tree->right,outfile,indent+2);
6249                 return ;
6250         case EQ_OP:
6251                 fprintf(outfile,"EQ(==) (%p) type (",tree);
6252                 printTypeChain(tree->ftype,outfile);
6253                 fprintf(outfile,")\n");
6254                 ast_print(tree->left,outfile,indent+2);
6255                 ast_print(tree->right,outfile,indent+2);
6256                 return ;
6257         case NE_OP:
6258                 fprintf(outfile,"NE(!=) (%p) type (",tree);
6259                 printTypeChain(tree->ftype,outfile);
6260                 fprintf(outfile,")\n");
6261                 ast_print(tree->left,outfile,indent+2);
6262                 ast_print(tree->right,outfile,indent+2);
6263                 /*------------------------------------------------------------------*/
6264                 /*----------------------------*/
6265                 /*             sizeof         */
6266                 /*----------------------------*/
6267         case SIZEOF:            /* evaluate wihout code generation */
6268                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6269                 return ;
6270
6271                 /*------------------------------------------------------------------*/
6272                 /*----------------------------*/
6273                 /* conditional operator  '?'  */
6274                 /*----------------------------*/
6275         case '?':
6276                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6277                 printTypeChain(tree->ftype,outfile);
6278                 fprintf(outfile,")\n");
6279                 ast_print(tree->left,outfile,indent+2);
6280                 ast_print(tree->right,outfile,indent+2);
6281                 return;
6282
6283         case ':':
6284                 fprintf(outfile,"COLON(:) (%p) type (",tree);
6285                 printTypeChain(tree->ftype,outfile);
6286                 fprintf(outfile,")\n");
6287                 ast_print(tree->left,outfile,indent+2);
6288                 ast_print(tree->right,outfile,indent+2);
6289                 return ;
6290
6291                 /*------------------------------------------------------------------*/
6292                 /*----------------------------*/
6293                 /*    assignment operators    */
6294                 /*----------------------------*/
6295         case MUL_ASSIGN:
6296                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6297                 printTypeChain(tree->ftype,outfile);
6298                 fprintf(outfile,")\n");
6299                 ast_print(tree->left,outfile,indent+2);
6300                 ast_print(tree->right,outfile,indent+2);
6301                 return;
6302         case DIV_ASSIGN:
6303                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6304                 printTypeChain(tree->ftype,outfile);
6305                 fprintf(outfile,")\n");
6306                 ast_print(tree->left,outfile,indent+2);
6307                 ast_print(tree->right,outfile,indent+2);
6308                 return;
6309         case AND_ASSIGN:
6310                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6311                 printTypeChain(tree->ftype,outfile);
6312                 fprintf(outfile,")\n");
6313                 ast_print(tree->left,outfile,indent+2);
6314                 ast_print(tree->right,outfile,indent+2);
6315                 return;
6316         case OR_ASSIGN:
6317                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6318                 printTypeChain(tree->ftype,outfile);
6319                 fprintf(outfile,")\n");
6320                 ast_print(tree->left,outfile,indent+2);
6321                 ast_print(tree->right,outfile,indent+2);
6322                 return;
6323         case XOR_ASSIGN:
6324                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6325                 printTypeChain(tree->ftype,outfile);
6326                 fprintf(outfile,")\n");
6327                 ast_print(tree->left,outfile,indent+2);
6328                 ast_print(tree->right,outfile,indent+2);
6329                 return;
6330         case RIGHT_ASSIGN:
6331                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6332                 printTypeChain(tree->ftype,outfile);
6333                 fprintf(outfile,")\n");
6334                 ast_print(tree->left,outfile,indent+2);
6335                 ast_print(tree->right,outfile,indent+2);
6336                 return;
6337         case LEFT_ASSIGN:
6338                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6339                 printTypeChain(tree->ftype,outfile);
6340                 fprintf(outfile,")\n");
6341                 ast_print(tree->left,outfile,indent+2);
6342                 ast_print(tree->right,outfile,indent+2);
6343                 return;
6344                 /*------------------------------------------------------------------*/
6345                 /*----------------------------*/
6346                 /*    -= operator             */
6347                 /*----------------------------*/
6348         case SUB_ASSIGN:
6349                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6350                 printTypeChain(tree->ftype,outfile);
6351                 fprintf(outfile,")\n");
6352                 ast_print(tree->left,outfile,indent+2);
6353                 ast_print(tree->right,outfile,indent+2);
6354                 return;
6355                 /*------------------------------------------------------------------*/
6356                 /*----------------------------*/
6357                 /*          += operator       */
6358                 /*----------------------------*/
6359         case ADD_ASSIGN:
6360                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6361                 printTypeChain(tree->ftype,outfile);
6362                 fprintf(outfile,")\n");
6363                 ast_print(tree->left,outfile,indent+2);
6364                 ast_print(tree->right,outfile,indent+2);
6365                 return;
6366                 /*------------------------------------------------------------------*/
6367                 /*----------------------------*/
6368                 /*      straight assignemnt   */
6369                 /*----------------------------*/
6370         case '=':
6371                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6372                 printTypeChain(tree->ftype,outfile);
6373                 fprintf(outfile,")\n");
6374                 ast_print(tree->left,outfile,indent+2);
6375                 ast_print(tree->right,outfile,indent+2);
6376                 return;
6377                 /*------------------------------------------------------------------*/
6378                 /*----------------------------*/
6379                 /*      comma operator        */
6380                 /*----------------------------*/
6381         case ',':
6382                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6383                 printTypeChain(tree->ftype,outfile);
6384                 fprintf(outfile,")\n");
6385                 ast_print(tree->left,outfile,indent+2);
6386                 ast_print(tree->right,outfile,indent+2);
6387                 return;
6388                 /*------------------------------------------------------------------*/
6389                 /*----------------------------*/
6390                 /*       function call        */
6391                 /*----------------------------*/
6392         case CALL:
6393         case PCALL:
6394                 fprintf(outfile,"CALL (%p) type (",tree);
6395                 printTypeChain(tree->ftype,outfile);
6396                 fprintf(outfile,")\n");
6397                 ast_print(tree->left,outfile,indent+2);
6398                 ast_print(tree->right,outfile,indent+2);
6399                 return;
6400         case PARAM:
6401                 fprintf(outfile,"PARMS\n");
6402                 ast_print(tree->left,outfile,indent+2);
6403                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6404                         ast_print(tree->right,outfile,indent+2);
6405                 }
6406                 return ;
6407                 /*------------------------------------------------------------------*/
6408                 /*----------------------------*/
6409                 /*     return statement       */
6410                 /*----------------------------*/
6411         case RETURN:
6412                 fprintf(outfile,"RETURN (%p) type (",tree);
6413                 if (tree->right) {
6414                     printTypeChain(tree->right->ftype,outfile);
6415                 }
6416                 fprintf(outfile,")\n");
6417                 ast_print(tree->right,outfile,indent+2);
6418                 return ;
6419                 /*------------------------------------------------------------------*/
6420                 /*----------------------------*/
6421                 /*     label statement        */
6422                 /*----------------------------*/
6423         case LABEL :
6424                 fprintf(outfile,"LABEL (%p)\n",tree);
6425                 ast_print(tree->left,outfile,indent+2);
6426                 ast_print(tree->right,outfile,indent);
6427                 return;
6428                 /*------------------------------------------------------------------*/
6429                 /*----------------------------*/
6430                 /*     switch statement       */
6431                 /*----------------------------*/
6432         case SWITCH:
6433                 {
6434                         value *val;
6435                         fprintf(outfile,"SWITCH (%p) ",tree);
6436                         ast_print(tree->left,outfile,0);
6437                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6438                                 INDENT(indent+2,outfile);
6439                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6440                                         (int) floatFromVal(val),
6441                                         tree->values.switchVals.swNum,
6442                                         (int) floatFromVal(val));
6443                         }
6444                         ast_print(tree->right,outfile,indent);
6445                 }
6446                 return ;
6447                 /*------------------------------------------------------------------*/
6448                 /*----------------------------*/
6449                 /* ifx Statement              */
6450                 /*----------------------------*/
6451         case IFX:
6452                 fprintf(outfile,"IF (%p) \n",tree);
6453                 ast_print(tree->left,outfile,indent+2);
6454                 if (tree->trueLabel) {
6455                         INDENT(indent+2,outfile);
6456                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6457                 }
6458                 if (tree->falseLabel) {
6459                         INDENT(indent+2,outfile);
6460                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6461                 }
6462                 ast_print(tree->right,outfile,indent+2);
6463                 return ;
6464                 /*----------------------------*/
6465                 /* goto Statement              */
6466                 /*----------------------------*/
6467         case GOTO:
6468                 fprintf(outfile,"GOTO (%p) \n",tree);
6469                 ast_print(tree->left,outfile,indent+2);
6470                 fprintf(outfile,"\n");
6471                 return ;
6472                 /*------------------------------------------------------------------*/
6473                 /*----------------------------*/
6474                 /* for Statement              */
6475                 /*----------------------------*/
6476         case FOR:
6477                 fprintf(outfile,"FOR (%p) \n",tree);
6478                 if (AST_FOR( tree, initExpr)) {
6479                         INDENT(indent+2,outfile);
6480                         fprintf(outfile,"INIT EXPR ");
6481                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6482                 }
6483                 if (AST_FOR( tree, condExpr)) {
6484                         INDENT(indent+2,outfile);
6485                         fprintf(outfile,"COND EXPR ");
6486                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6487                 }
6488                 if (AST_FOR( tree, loopExpr)) {
6489                         INDENT(indent+2,outfile);
6490                         fprintf(outfile,"LOOP EXPR ");
6491                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6492                 }
6493                 fprintf(outfile,"FOR LOOP BODY \n");
6494                 ast_print(tree->left,outfile,indent+2);
6495                 return ;
6496         case CRITICAL:
6497                 fprintf(outfile,"CRITICAL (%p) \n",tree);
6498                 ast_print(tree->left,outfile,indent+2);
6499         default:
6500             return ;
6501         }
6502 }
6503
6504 void PA(ast *t)
6505 {
6506         ast_print(t,stdout,0);
6507 }
6508
6509
6510
6511 /*-----------------------------------------------------------------*/
6512 /* astErrors : returns non-zero if errors present in tree          */
6513 /*-----------------------------------------------------------------*/
6514 int astErrors(ast *t)
6515 {
6516   int errors=0;
6517
6518   if (t)
6519     {
6520       if (t->isError)
6521         errors++;
6522
6523       if (t->type == EX_VALUE
6524           && t->opval.val->sym
6525           && t->opval.val->sym->undefined)
6526         errors++;
6527
6528       errors += astErrors(t->left);
6529       errors += astErrors(t->right);
6530     }
6531
6532   return errors;
6533 }