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