Type safe newAst, fixes various warnings.
[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 #include "common.h"
26
27 int currLineno  = 0;
28 set *astList = NULL ;
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
31 int labelKey = 1 ;
32
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
45 #define ALLOCATE 1
46 #define DEALLOCATE 2
47
48 char  buffer[1024];
49 int noLineno = 0;
50 int noAlloc = 0 ;
51 symbol *currFunc ;
52 ast  *createIval  (ast *, link *, initList *, ast *);
53 ast *createIvalCharPtr (ast *, link *, ast *);
54 ast *optimizeRRCRLC ( ast * );
55 ast *optimizeGetHbit(ast *);
56 ast *backPatchLabels (ast *,symbol *,symbol *);
57 int  inInitMode = 0;
58 FILE *codeOutFile ;
59 int ptt(ast *tree) {
60     printTypeChain(tree->ftype,stdout);
61     return 0;
62 }
63      
64
65 /*-----------------------------------------------------------------*/
66 /* newAst - creates a fresh node for an expression tree           */
67 /*-----------------------------------------------------------------*/
68 #if 0
69 ast  *newAst (int  type, void *op )
70 {
71     ast  *ex ;
72     static int oldLineno = 0 ;
73
74     ALLOC(ex,sizeof(ast));    
75     
76     ex->type = type ;           
77     ex->lineno = (noLineno ? oldLineno : yylineno);
78     ex->filename = currFname ;
79     ex->level = NestLevel ;
80     ex->block = currBlockno ;
81     ex->initMode = inInitMode;
82
83     /* depending on the type */
84     switch (type)   {
85     case  EX_VALUE :
86         ex->opval.val = (value *) op;
87         break ;
88     case EX_OP     :
89         ex->opval.op   = (long) op ;
90         break ;
91     case EX_LINK   :
92         ex->opval.lnk  = (link *) op;
93         break ;
94     case EX_STMNT  :
95         ex->opval.stmnt= (unsigned) op;
96     }
97     
98     return ex;
99 }
100 #endif
101
102 static ast* newAst_(unsigned type)
103 {
104     ast  *ex ;
105     static int oldLineno = 0 ;
106
107     ALLOC(ex,sizeof(ast));    
108     
109     ex->type = type ;           
110     ex->lineno = (noLineno ? oldLineno : yylineno);
111     ex->filename = currFname ;
112     ex->level = NestLevel ;
113     ex->block = currBlockno ;
114     ex->initMode = inInitMode;
115     return ex;
116 }
117
118 ast* newAst_VALUE(value*val)
119 {
120       ast* ex = newAst_(EX_VALUE);
121       ex->opval.val = val;
122       return ex;
123 }
124
125 ast* newAst_OP(unsigned op)
126 {
127       ast*ex = newAst_(EX_OP);
128       ex->opval.op = op;
129       return ex;
130 }
131
132 ast* newAst_LINK(link*val)
133 {
134       ast* ex = newAst_(EX_LINK);
135       ex->opval.lnk = val;
136       return ex;
137 }
138
139 ast* newAst_STMNT(unsigned val)
140 {
141       ast* ex = newAst_(EX_STMNT);
142       ex->opval.stmnt = val;
143       return ex;
144 }
145
146 /*-----------------------------------------------------------------*/
147 /* newNode - creates a new node                                    */
148 /*-----------------------------------------------------------------*/
149 ast  *newNode ( long op,   ast  *left, ast *right   )
150 {
151     ast  *ex ;
152     
153     ex = newAst_OP(op) ;
154     ex->left    = left ;
155     ex->right   = right;
156         
157     return ex ;
158 }
159
160 /*-----------------------------------------------------------------*/
161 /* newIfxNode - creates a new Ifx Node                             */
162 /*-----------------------------------------------------------------*/
163 ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel)
164 {
165     ast *ifxNode ;
166     
167     /* if this is a literal then we already know the result */
168     if (condAst->etype && IS_LITERAL(condAst->etype)) {
169         
170         /* then depending on the expression value */
171         if ( floatFromVal(condAst->opval.val) )
172               ifxNode = newNode(GOTO,
173                                 newAst_VALUE(symbolVal(trueLabel)),
174                                 NULL);
175         else
176               ifxNode = newNode(GOTO,
177                                 newAst_VALUE(symbolVal(falseLabel)),
178                                 NULL);
179     }
180     else {
181         ifxNode = newNode(IFX,condAst,NULL);
182         ifxNode->trueLabel = trueLabel;
183         ifxNode->falseLabel= falseLabel;
184     }
185     
186     return ifxNode ;
187 }
188
189 /*-----------------------------------------------------------------*/
190 /* copyAstValues - copies value portion of ast if needed           */
191 /*-----------------------------------------------------------------*/
192 void copyAstValues (ast *dest,ast *src)
193 {
194     switch (src->opval.op) {
195     case BLOCK:
196         dest->values.sym     = copySymbolChain(src->values.sym);
197         break;
198         
199     case SWITCH:
200         dest->values.switchVals.swVals = 
201             copyValue(src->values.switchVals.swVals);
202         dest->values.switchVals.swDefault =
203             src->values.switchVals.swDefault ;
204         dest->values.switchVals.swNum  =
205             src->values.switchVals.swNum ;
206         break ;
207         
208     case INLINEASM:
209         ALLOC_ATOMIC(dest->values.inlineasm,strlen(src->values.inlineasm));
210         strcpy(dest->values.inlineasm,src->values.inlineasm);
211
212     case FOR:
213          AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel));
214          AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel));
215          AST_FOR(dest,falseLabel) =  copySymbol(AST_FOR(src,falseLabel));
216          AST_FOR(dest,condLabel)  =  copySymbol(AST_FOR(src,condLabel));
217          AST_FOR(dest,initExpr)   =  copyAst (AST_FOR(src,initExpr)) ;
218          AST_FOR(dest,condExpr)   =  copyAst (AST_FOR(src,condExpr)) ;
219          AST_FOR(dest,loopExpr)   =  copyAst (AST_FOR(src,loopExpr)) ;
220     }
221     
222 }
223
224 /*-----------------------------------------------------------------*/
225 /* copyAst - makes a copy of a given astession                     */
226 /*-----------------------------------------------------------------*/
227 ast  *copyAst (ast   *src)
228 {
229     ast  *dest;
230     
231     if (!src)  return NULL ;
232    
233     ALLOC(dest,sizeof(ast));
234     
235     dest->type = src->type  ;
236     dest->lineno = src->lineno ;
237     dest->level  = src->level  ;
238     dest->funcName = src->funcName;
239     dest->argSym = src->argSym;
240     
241     /* if this is a leaf */   
242     /* if value */
243     if (src->type == EX_VALUE)   {
244         dest->opval.val = copyValue(src->opval.val);
245         goto exit;
246     }
247     
248     /* if link */
249     if (src->type == EX_LINK)   {
250         dest->opval.lnk = copyLinkChain(src->opval.lnk);
251         goto exit ;
252     }
253     
254     dest->opval.op = src->opval.op ;
255     
256     /* if this is a node that has special values */
257     copyAstValues (dest,src);
258     
259     if ( src->ftype ) 
260         dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ;
261     
262     dest->trueLabel = copySymbol (src->trueLabel);
263     dest->falseLabel= copySymbol (src->falseLabel);
264     dest->left = copyAst(src->left);
265     dest->right= copyAst(src->right);
266  exit:
267     return dest ;
268     
269 }
270
271 /*-----------------------------------------------------------------*/
272 /* hasSEFcalls - returns TRUE if tree has a function call          */
273 /*-----------------------------------------------------------------*/
274 bool hasSEFcalls ( ast *tree)
275 {
276     if (!tree)
277         return FALSE ;
278
279     if (tree->type == EX_OP && 
280         ( tree->opval.op == CALL  ||
281           tree->opval.op == PCALL ||
282           tree->opval.op == '='   ||
283           tree->opval.op == INC_OP ||
284           tree->opval.op == DEC_OP ))
285         return TRUE;
286
287     return ( hasSEFcalls(tree->left) |
288              hasSEFcalls(tree->right));
289 }
290
291 /*-----------------------------------------------------------------*/
292 /* isAstEqual - compares two asts & returns 1 if they are equal    */
293 /*-----------------------------------------------------------------*/
294 int isAstEqual (ast *t1, ast *t2)
295 {
296     if (!t1 && !t2)
297         return 1;
298
299     if (!t1 || !t2)
300         return 0;
301
302     /* match type */
303     if (t1->type != t2->type)
304         return 0;
305
306     switch (t1->type) {
307     case EX_OP:
308         if (t1->opval.op != t2->opval.op)
309             return 0;
310         return ( isAstEqual(t1->left,t2->left) &&
311                  isAstEqual(t1->right,t2->right));
312         break;
313
314     case EX_VALUE:
315         if (t1->opval.val->sym) {
316             if (!t2->opval.val->sym)
317                 return 0;
318             else
319                 return isSymbolEqual(t1->opval.val->sym,
320                                      t2->opval.val->sym);
321         }
322         else {
323             if (t2->opval.val->sym)
324                 return 0;
325             else
326                 return (floatFromVal(t1->opval.val) ==
327                         floatFromVal(t2->opval.val));
328         }
329         break;
330
331         /* only compare these two types */
332     default :
333         return 0;
334     }
335
336     return 0;
337 }
338
339 /*-----------------------------------------------------------------*/
340 /* resolveSymbols - resolve symbols from the symbol table          */
341 /*-----------------------------------------------------------------*/
342 ast *resolveSymbols (ast *tree)
343 {
344     /* walk the entire tree and check for values */
345     /* with symbols if we find one then replace  */
346     /* symbol with that from the symbol table    */
347     
348     if ( tree == NULL )
349         return tree ;
350
351     /* print the line          */
352     /* if not block & function */
353     if ( tree->type == EX_OP && 
354          ( tree->opval.op != FUNCTION  &&
355            tree->opval.op != BLOCK     &&
356            tree->opval.op != NULLOP    )) {
357         filename = tree->filename ;
358         lineno = tree->lineno ;
359     }
360
361     /* make sure we resolve the true & false labels for ifx */
362     if (tree->type == EX_OP && tree->opval.op == IFX ) {
363         symbol *csym ;
364
365         if (tree->trueLabel) {
366             if (( csym = findSym(LabelTab,tree->trueLabel,
367                                  tree->trueLabel->name)))
368                 tree->trueLabel = csym ;
369             else
370                 werror(E_LABEL_UNDEF,tree->trueLabel->name);
371         }
372
373         if (tree->falseLabel) {
374             if (( csym = findSym(LabelTab,
375                                  tree->falseLabel,
376                                  tree->falseLabel->name)))
377                 tree->falseLabel = csym ;
378             else
379                 werror(E_LABEL_UNDEF,tree->falseLabel->name);       
380         }
381
382     }
383
384     /* if this is a label resolve it from the labelTab*/
385     if (IS_AST_VALUE(tree)   &&      
386         tree->opval.val->sym &&
387         tree->opval.val->sym->islbl) {
388         
389         symbol *csym = findSym (LabelTab, tree->opval.val->sym , 
390                                 tree->opval.val->sym->name);
391
392         if (!csym) 
393             werror (E_LABEL_UNDEF,tree->opval.val->sym->name);
394         else        
395             tree->opval.val->sym = csym ;       
396
397         goto resolveChildren ;
398     }
399
400     /* do only for leafs */
401     if (IS_AST_VALUE(tree)   && 
402         tree->opval.val->sym && 
403         ! tree->opval.val->sym->implicit ) {
404
405         symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym);
406         
407         /* if found in the symbol table & they r not the same */
408         if (csym && tree->opval.val->sym != csym ) {      
409             tree->opval.val->sym = csym ;          
410             tree->opval.val->type = csym->type;
411             tree->opval.val->etype = csym->etype;
412         }
413         
414         /* if not found in the symbol table */
415         /* mark it as undefined assume it is*/
416         /* an integer in data space         */
417         if (!csym && !tree->opval.val->sym->implicit) {
418             
419             /* if this is a function name then */
420             /* mark it as returning an int     */
421             if (tree->funcName) {
422                 tree->opval.val->sym->type = newLink();
423                 DCL_TYPE(tree->opval.val->sym->type) = FUNCTION;
424                 tree->opval.val->sym->type->next = 
425                     tree->opval.val->sym->etype = newIntLink();
426                 tree->opval.val->etype = tree->opval.val->etype;
427                 tree->opval.val->type = tree->opval.val->sym->type;
428                 werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name);
429             } else {
430                 tree->opval.val->sym->undefined =1 ;
431                 tree->opval.val->type = 
432                     tree->opval.val->etype = newIntLink();
433                 tree->opval.val->sym->type = 
434                     tree->opval.val->sym->etype = newIntLink();
435             }
436         }       
437     }  
438
439  resolveChildren:    
440     resolveSymbols (tree->left);
441     resolveSymbols (tree->right);
442     
443     return tree;
444 }
445
446 /*-----------------------------------------------------------------*/
447 /* setAstLineno - walks a ast tree & sets the line number          */
448 /*-----------------------------------------------------------------*/
449 int setAstLineno ( ast *tree, int lineno)
450 {
451     if (!tree)
452         return 0;
453
454     tree->lineno = lineno ;
455     setAstLineno ( tree->left, lineno);
456     setAstLineno ( tree->right, lineno);
457     return 0;
458 }
459
460 #if 0
461 /* this functions seems to be superfluous?! kmh */
462
463 /*-----------------------------------------------------------------*/
464 /* resolveFromTable - will return the symbal table value           */
465 /*-----------------------------------------------------------------*/
466 value *resolveFromTable (value *val)
467 {
468     symbol *csym ;
469
470     if (!val->sym)
471         return val;
472
473     csym = findSymWithLevel (SymbolTab,val->sym);
474             
475     /* if found in the symbol table & they r not the same */
476     if (csym && val->sym != csym && 
477         csym->level == val->sym->level &&
478         csym->_isparm &&
479         !csym->ismyparm) {
480       
481         val->sym = csym ;      
482         val->type = csym->type;
483         val->etype = csym->etype;
484     }  
485
486     return val;
487 }
488 #endif
489
490 /*-----------------------------------------------------------------*/
491 /* funcOfType :- function of type with name                        */
492 /*-----------------------------------------------------------------*/
493 symbol *funcOfType (char *name, link *type, link *argType, 
494                     int nArgs , int rent)
495 {
496     symbol *sym;    
497     int argStack = 0;   
498     /* create the symbol */
499     sym = newSymbol (name,0);
500         
501     /* if arguments required */
502     if (nArgs) {
503
504         value *args ;
505         args = sym->args = newValue();
506
507         while (nArgs--) {
508             argStack += getSize(type);
509             args->type = copyLinkChain(argType);
510             args->etype = getSpec(args->type);
511             if (!nArgs)
512                 break;
513             args = args->next = newValue();
514         }
515     }
516     
517     /* setup return value       */
518     sym->type = newLink();
519     DCL_TYPE(sym->type) = FUNCTION;
520     sym->type->next = copyLinkChain(type);
521     sym->etype = getSpec(sym->type);   
522     SPEC_RENT(sym->etype) = rent;
523     
524     /* save it */
525     addSymChain(sym);
526     sym->cdef = 1;
527     sym->argStack = (rent ? argStack : 0);
528     allocVariables (sym);
529     return sym;
530     
531 }
532
533 /*-----------------------------------------------------------------*/
534 /* reverseParms - will reverse a parameter tree                    */
535 /*-----------------------------------------------------------------*/
536 void reverseParms (ast *ptree)
537 {
538     ast *ttree;
539     if (!ptree)
540         return ;
541
542     /* top down if we find a nonParm tree then quit */
543     if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
544         ttree = ptree->left;
545         ptree->left = ptree->right;
546         ptree->right = ttree;
547         reverseParms(ptree->left);
548         reverseParms(ptree->right);
549     }
550
551     return ;
552 }
553
554 /*-----------------------------------------------------------------*/
555 /* processParms  - makes sure the parameters are okay and do some  */
556 /*                 processing with them                            */
557 /*-----------------------------------------------------------------*/
558 int processParms (ast *func, value *defParm, 
559                   ast *actParm, 
560                   int *parmNumber)
561 {
562     link *fetype = func->etype;
563     
564     /* if none of them exist */
565     if ( !defParm && !actParm)
566         return 0;
567      
568     /* if the function is being called via a pointer &   */
569     /* it has not been defined a reentrant then we cannot*/
570     /* have parameters                                   */
571     if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
572         werror (E_NONRENT_ARGS);  
573         return 1;
574     }
575     
576     /* if defined parameters ended but actual parameters */
577     /* exist and this is not defined as a variable arg   */
578     /* also check if statckAuto option is specified      */
579     if ((! defParm) && actParm && (!func->hasVargs ) && 
580         !options.stackAuto && !IS_RENT(fetype)) {
581         werror(E_TOO_MANY_PARMS);
582         return 1;
583     }
584     
585     /* if defined parameters present and actual paramters ended */
586     if ( defParm && ! actParm) {
587         werror(E_TO_FEW_PARMS);
588         return 1;
589     }
590         
591     /* if defined parameters ended but actual has not & */
592     /* has a variable argument list or statckAuto       */
593     if (! defParm && actParm && 
594         (func->hasVargs || options.stackAuto || IS_RENT(fetype)))
595         return 0;
596     
597     resolveSymbols(actParm);
598     /* if this is a PARAM node then match left & right */
599     if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
600         
601         return (processParms (func,defParm,actParm->left,parmNumber) ||
602                 processParms (func,defParm->next, actParm->right,parmNumber) );
603     }
604        
605     /* the parameter type must be atleast castable */
606     if (checkType(defParm->type,actParm->ftype) == 0) {
607         werror(E_TYPE_MISMATCH_PARM,*parmNumber);
608         werror(E_CONTINUE,"defined type ");
609         printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
610         werror(E_CONTINUE,"actual type ");
611         printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
612     }
613     
614     /* if the parameter is castable then add the cast */
615     if ( checkType (defParm->type,actParm->ftype) < 0) {
616         ast *pTree = resolveSymbols(copyAst(actParm));
617
618         /* now change the current one to a cast */      
619         actParm->type = EX_OP ;
620         actParm->opval.op = CAST ;
621         actParm->left = newAst_LINK(defParm->type);
622         actParm->right= pTree ;
623         actParm->etype= defParm->etype;
624         actParm->ftype= defParm->type;
625     }
626     
627 /*    actParm->argSym = resolveFromTable(defParm)->sym ; */
628     actParm->argSym = defParm->sym;
629     /* make a copy and change the regparm type to the defined parm */
630     actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
631     SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
632     (*parmNumber)++;
633     return 0;
634 }
635 /*-----------------------------------------------------------------*/
636 /* createIvalType - generates ival for basic types                 */
637 /*-----------------------------------------------------------------*/
638 ast *createIvalType ( ast *sym,link  *type, initList *ilist)
639 {
640     ast *iExpr;
641
642     /* if initList is deep */
643     if ( ilist->type == INIT_DEEP )
644         ilist =  ilist->init.deep  ;
645     
646     iExpr = decorateType(resolveSymbols(list2expr(ilist)));
647     return decorateType(newNode('=',sym,iExpr));
648 }
649
650 /*-----------------------------------------------------------------*/
651 /* createIvalStruct - generates initial value for structures       */
652 /*-----------------------------------------------------------------*/
653 ast *createIvalStruct (ast *sym,link *type,initList *ilist)
654 {
655     ast *rast = NULL ;
656     symbol   *sflds  ;
657     initList *iloop  ;
658     
659     sflds = SPEC_STRUCT(type)->fields  ;
660     if (ilist->type != INIT_DEEP) {
661         werror(E_INIT_STRUCT,"");
662         return NULL ;
663     }
664     
665     iloop = ilist->init.deep;
666     
667     for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
668         ast *lAst ;
669         
670         /* if we have come to end */
671         if (!iloop)
672             break;
673         sflds->implicit = 1;
674         lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
675         lAst = decorateType(resolveSymbols(lAst));
676         rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
677     }
678     return rast ;
679 }
680
681
682 /*-----------------------------------------------------------------*/
683 /* createIvalArray - generates code for array initialization       */
684 /*-----------------------------------------------------------------*/
685 ast *createIvalArray (ast  *sym, link *type, initList *ilist)
686 {
687     ast *rast = NULL;
688     initList *iloop ;
689     int lcnt = 0, size =0 ;
690     
691     /* take care of the special   case  */
692     /* array of characters can be init  */
693     /* by a string                      */
694     if ( IS_CHAR(type->next) )
695         if ( (rast = createIvalCharPtr(sym,
696                                        type,
697                                        decorateType(resolveSymbols(list2expr(ilist))))))
698             
699             return decorateType(resolveSymbols(rast));
700     
701     /* not the special case             */
702     if (ilist->type != INIT_DEEP) {
703         werror(E_INIT_STRUCT,"");
704         return NULL;
705     }
706     
707     iloop = ilist->init.deep   ;
708     lcnt = DCL_ELEM(type);
709     
710     for (;;)  {
711         ast *aSym ;
712         size++ ;
713
714         aSym = newNode('[',sym,newAst_VALUE(valueFromLit(size-1)));
715         aSym = decorateType(resolveSymbols(aSym));
716         rast = createIval (aSym,type->next,iloop,rast)   ;
717         iloop = (iloop ? iloop->next : NULL) ;
718         if (!iloop)
719             break;
720         /* if not array limits given & we */
721         /* are out of initialisers then   */
722         if (!DCL_ELEM(type) && !iloop)
723             break ;
724         
725         /* no of elements given and we    */
726         /* have generated for all of them */
727         if (!--lcnt)
728             break ;
729     }
730     
731     /* if we have not been given a size  */
732     if (!DCL_ELEM(type))
733         DCL_ELEM(type) = size;
734     
735     return decorateType(resolveSymbols(rast));
736 }
737
738
739 /*-----------------------------------------------------------------*/
740 /* createIvalCharPtr - generates initial values for char pointers  */
741 /*-----------------------------------------------------------------*/
742 ast *createIvalCharPtr (ast *sym, link *type, ast *iexpr)
743 {      
744     ast *rast = NULL ;
745
746     /* if this is a pointer & right is a literal array then */
747     /* just assignment will do                              */
748     if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) || 
749           SPEC_SCLS(iexpr->etype) == S_CODE )
750                           && IS_ARRAY(iexpr->ftype))) 
751         return newNode('=',sym,iexpr);
752
753     /* left side is an array so we have to assign each */
754     /* element                                         */
755     if (( IS_LITERAL(iexpr->etype) || 
756           SPEC_SCLS(iexpr->etype) == S_CODE )
757         && IS_ARRAY(iexpr->ftype))  {
758
759         /* for each character generate an assignment */
760         /* to the array element */
761         char *s = SPEC_CVAL(iexpr->etype).v_char ;
762         int i = 0 ;
763         
764         while (*s) {        
765             rast = newNode(NULLOP,
766                            rast,
767                            newNode('=',
768                                    newNode('[', sym,
769                                            newAst_VALUE(valueFromLit(i))),
770                                    newAst_VALUE(valueFromLit(*s))));
771             i++;
772             s++;
773         }
774         rast = newNode(NULLOP,
775                            rast,
776                            newNode('=',
777                                    newNode('[', sym,
778                                            newAst_VALUE(valueFromLit(i))),
779                                    newAst_VALUE(valueFromLit(*s))));
780         return decorateType(resolveSymbols(rast));
781     }
782
783     return NULL ;
784 }
785
786 /*-----------------------------------------------------------------*/
787 /* createIvalPtr - generates initial value for pointers            */
788 /*-----------------------------------------------------------------*/
789 ast *createIvalPtr (ast *sym,link *type,initList *ilist)
790 {    
791     ast *rast;
792     ast *iexpr ;
793
794     /* if deep then   */
795     if ( ilist->type == INIT_DEEP )
796         ilist = ilist->init.deep   ;
797            
798     iexpr = decorateType(resolveSymbols(list2expr(ilist)));
799
800     /* if character pointer */
801     if (IS_CHAR(type->next))
802         if ((rast = createIvalCharPtr (sym,type,iexpr)))
803             return rast;   
804
805     return newNode('=',sym,iexpr);          
806 }
807
808 /*-----------------------------------------------------------------*/
809 /* createIval - generates code for initial value                   */
810 /*-----------------------------------------------------------------*/
811 ast  *createIval  (ast *sym, link *type, initList *ilist, ast *wid)
812 {
813     ast *rast = NULL;  
814
815     if (!ilist)
816         return NULL ;   
817     
818     /* if structure then    */
819     if (IS_STRUCT(type)) 
820         rast =  createIvalStruct(sym, type,ilist);
821     else
822         /* if this is a pointer */
823         if (IS_PTR(type)) 
824             rast = createIvalPtr(sym, type,ilist);
825         else
826             /* if this is an array   */
827             if (IS_ARRAY(type))  
828                 rast = createIvalArray(sym, type,ilist); 
829             else
830                 /* if type is SPECIFIER */
831                 if (IS_SPEC(type))
832                     rast =  createIvalType (sym,type,ilist);
833     if ( wid )
834         return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
835     else
836         return decorateType(resolveSymbols(rast)) ;
837 }
838
839 /*-----------------------------------------------------------------*/
840 /* initAggregates - initialises aggregate variables with initv     */
841 /*-----------------------------------------------------------------*/
842 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
843 {
844     return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
845 }
846
847 /*-----------------------------------------------------------------*/
848 /* gatherAutoInit - creates assignment expressions for initial     */
849 /*      values                                                     */
850 /*-----------------------------------------------------------------*/
851 ast     *gatherAutoInit ( symbol *autoChain )
852 {
853     ast *init = NULL ;
854     ast *work ;
855     symbol      *sym;
856     
857     inInitMode =1;
858     for ( sym = autoChain ; sym ; sym = sym->next ) {
859         
860         /* resolve the symbols in the ival */
861         if (sym->ival)
862             resolveIvalSym(sym->ival);
863
864         /* if this is a static variable & has an */
865         /* initial value the code needs to be lifted */
866         /* here to the main portion since they can be */
867         /* initialised only once at the start    */
868         if ( IS_STATIC(sym->etype) && sym->ival &&
869              SPEC_SCLS(sym->etype) != S_CODE) {
870             symbol *newSym ;
871
872             /* insert the symbol into the symbol table */
873             /* with level = 0 & name = rname               */
874             newSym = copySymbol (sym);                      
875             addSym (SymbolTab,newSym,newSym->name,0,0);
876             
877             /* now lift the code to main */
878             if (IS_AGGREGATE(sym->type))
879                 work = initAggregates (sym, sym->ival,NULL);
880             else
881                 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
882                                list2expr(sym->ival));
883             
884             setAstLineno(work,sym->lineDef);
885
886             sym->ival = NULL ;
887             if ( staticAutos )
888                 staticAutos = newNode(NULLOP,staticAutos,work);
889             else
890                 staticAutos = work ;
891             
892             continue;
893         }
894         
895         /* if there is an initial value */
896         if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
897             if (IS_AGGREGATE(sym->type)) 
898                 work = initAggregates (sym,sym->ival,NULL);
899             else
900                 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
901                                list2expr(sym->ival));
902             
903             setAstLineno (work,sym->lineDef);
904             sym->ival = NULL ;
905             if ( init )
906                 init = newNode(NULLOP,init,work);
907             else
908                 init = work ;
909         }
910     }
911     inInitMode = 0;
912     return init ;
913 }
914
915 /*-----------------------------------------------------------------*/
916 /* stringToSymbol - creates a symbol from a literal string         */
917 /*-----------------------------------------------------------------*/
918 static value *stringToSymbol (value *val)
919 {
920     char name[SDCC_NAME_MAX+1];
921     static int charLbl = 0;
922     symbol *sym ;
923     
924     sprintf(name,"_str_%d",charLbl++);
925     sym = newSymbol(name,0); /* make it @ level 0 */
926     strcpy(sym->rname,name);
927     
928     /* copy the type from the value passed */   
929     sym->type = copyLinkChain(val->type);
930     sym->etype = getSpec(sym->type);
931     /* change to storage class & output class */
932     SPEC_SCLS(sym->etype) = S_CODE ;
933     SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
934     SPEC_STAT(sym->etype) = 1;
935     /* make the level & block = 0 */
936     sym->block = sym->level = 0;
937     sym->isstrlit = 1;
938     /* create an ival */
939     sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
940     if (noAlloc == 0) {
941         /* allocate it */
942         addSymChain(sym);
943         allocVariables(sym);
944     }
945     sym->ival = NULL;
946     return symbolVal(sym);
947     
948 }
949
950 /*-----------------------------------------------------------------*/
951 /* processBlockVars - will go thru the ast looking for block if    */
952 /*                    a block is found then will allocate the syms */
953 /*                    will also gather the auto inits present      */
954 /*-----------------------------------------------------------------*/
955 ast *processBlockVars ( ast *tree , int *stack, int action)
956 {
957     if (! tree)
958         return NULL ;
959     
960     /* if this is a block */
961     if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
962         ast *autoInit ;
963         
964         if (action == ALLOCATE) {
965             autoInit = gatherAutoInit (tree->values.sym);
966             *stack += allocVariables (tree->values.sym);
967             
968             /* if there are auto inits then do them */
969             if (autoInit)
970                 tree->left = newNode(NULLOP,autoInit,tree->left);
971         } else /* action is deallocate */
972             deallocLocal (tree->values.sym) ;
973     }
974     
975     processBlockVars (tree->left, stack, action);
976     processBlockVars (tree->right, stack, action);
977     return tree ;
978 }
979
980 /*-----------------------------------------------------------------*/
981 /* constExprValue - returns the value of a constant expression     */
982 /*-----------------------------------------------------------------*/
983 value *constExprValue (ast *cexpr, int check)
984 {
985     cexpr = decorateType(resolveSymbols(cexpr));
986
987     /* if this is not a constant then */
988     if (!IS_LITERAL(cexpr->ftype)) {
989         /* then check if this is a literal array
990            in code segment */
991         if (SPEC_SCLS(cexpr->etype) == S_CODE &&
992             SPEC_CVAL(cexpr->etype).v_char    &&
993             IS_ARRAY(cexpr->ftype)) {
994             value *val = valFromType(cexpr->ftype);
995             SPEC_SCLS(val->etype) = S_LITERAL;
996             val->sym =cexpr->opval.val->sym ; 
997             val->sym->type = copyLinkChain(cexpr->ftype);
998             val->sym->etype = getSpec(val->sym->type);
999             strcpy(val->name,cexpr->opval.val->sym->rname);
1000             return val;
1001         }
1002         
1003         /* if we are casting a literal value then */
1004         if (IS_AST_OP(cexpr)        &&
1005             cexpr->opval.op == CAST &&
1006             IS_LITERAL(cexpr->left->ftype))
1007             return valCastLiteral(cexpr->ftype,
1008                                   floatFromVal(cexpr->left->opval.val));
1009
1010         if (IS_AST_VALUE(cexpr))
1011             return cexpr->opval.val;
1012         
1013         if (check)         
1014             werror(E_CONST_EXPECTED,"found expression");
1015
1016         return NULL ;
1017     }
1018     
1019     /* return the value */
1020     return cexpr->opval.val ;
1021     
1022 }
1023
1024 /*-----------------------------------------------------------------*/
1025 /* isLabelInAst - will return true if a given label is found       */
1026 /*-----------------------------------------------------------------*/
1027 bool isLabelInAst (symbol *label, ast *tree)
1028 {
1029     if (!tree  || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1030         return FALSE ;
1031
1032     if (IS_AST_OP(tree) &&
1033         tree->opval.op == LABEL &&
1034         isSymbolEqual(AST_SYMBOL(tree->left),label))
1035         return TRUE;
1036
1037     return isLabelInAst(label,tree->right) &&
1038         isLabelInAst(label,tree->left);
1039         
1040 }
1041
1042 /*-----------------------------------------------------------------*/
1043 /* isLoopCountable - return true if the loop count can be determi- */
1044 /* -ned at compile time .                                          */
1045 /*-----------------------------------------------------------------*/
1046 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1047                       symbol **sym,ast **init, ast **end) 
1048 {
1049     
1050     /* the loop is considered countable if the following
1051        conditions are true :-
1052
1053        a) initExpr :- <sym> = <const>
1054        b) condExpr :- <sym> < <const1>
1055        c) loopExpr :- <sym> ++ 
1056     */
1057
1058     /* first check the initExpr */
1059     if ( IS_AST_OP(initExpr)       &&
1060          initExpr->opval.op == '=' && /* is assignment */
1061          IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */     
1062         
1063         *sym = AST_SYMBOL(initExpr->left);
1064         *init= initExpr->right;
1065     }
1066     else
1067         return FALSE;
1068     
1069     /* for now the symbol has to be of
1070        integral type */
1071     if (!IS_INTEGRAL((*sym)->type))
1072         return FALSE;
1073
1074     /* now check condExpr */
1075     if (IS_AST_OP(condExpr)) {
1076
1077         switch (condExpr->opval.op) {
1078         case '<':
1079             if (IS_AST_SYM_VALUE(condExpr->left) &&
1080                 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1081                 IS_AST_LIT_VALUE(condExpr->right)) {
1082                 *end = condExpr->right;
1083                 break;
1084             }
1085             return FALSE;
1086             
1087         case '!':
1088             if (IS_AST_OP(condExpr->left) &&
1089                 condExpr->left->opval.op == '>' &&
1090                 IS_AST_LIT_VALUE(condExpr->left->right) &&
1091                 IS_AST_SYM_VALUE(condExpr->left->left)&&
1092                 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1093                 
1094                 *end = newNode('+', condExpr->left->right,
1095                                newAst_VALUE(constVal("1")));
1096                 break;
1097             }
1098             return FALSE ;
1099             
1100         default:
1101             return FALSE ;
1102         }       
1103         
1104     }          
1105
1106     /* check loop expression is of the form <sym>++ */
1107     if (!IS_AST_OP(loopExpr))
1108         return FALSE ;
1109
1110     /* check if <sym> ++ */
1111     if (loopExpr->opval.op == INC_OP) {
1112                 
1113         if (loopExpr->left) {
1114             /* pre */
1115             if (IS_AST_SYM_VALUE(loopExpr->left) &&
1116                 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1117                 return TRUE ;      
1118                 
1119         } else {
1120             /* post */
1121             if (IS_AST_SYM_VALUE(loopExpr->right) &&
1122                 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1123                 return TRUE ; 
1124         }
1125             
1126     } 
1127     else {
1128         /* check for += */
1129         if ( loopExpr->opval.op == ADD_ASSIGN ) {
1130
1131             if (IS_AST_SYM_VALUE(loopExpr->left) &&
1132                 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1133                 IS_AST_LIT_VALUE(loopExpr->right) &&
1134                 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1135                 return TRUE ;
1136         }               
1137     }
1138     
1139     return FALSE;
1140 }
1141
1142 /*-----------------------------------------------------------------*/
1143 /* astHasVolatile - returns true if ast contains any volatile      */
1144 /*-----------------------------------------------------------------*/
1145 bool astHasVolatile (ast *tree)
1146 {
1147     if (!tree)
1148         return FALSE ;
1149
1150     if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1151         return TRUE;
1152
1153     if (IS_AST_OP(tree))
1154         return astHasVolatile(tree->left) ||
1155             astHasVolatile(tree->right);
1156     else
1157         return FALSE ;
1158 }
1159
1160 /*-----------------------------------------------------------------*/
1161 /* astHasPointer - return true if the ast contains any ptr variable*/
1162 /*-----------------------------------------------------------------*/
1163 bool astHasPointer (ast *tree)
1164 {
1165     if (!tree)
1166         return FALSE ;
1167
1168     if (IS_AST_LINK(tree))
1169         return TRUE;
1170
1171     /* if we hit an array expression then check
1172        only the left side */
1173     if (IS_AST_OP(tree) && tree->opval.op == '[')
1174         return astHasPointer(tree->left);
1175
1176     if (IS_AST_VALUE(tree))
1177             return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1178
1179     return astHasPointer(tree->left) ||
1180         astHasPointer(tree->right);
1181         
1182 }
1183
1184 /*-----------------------------------------------------------------*/
1185 /* astHasSymbol - return true if the ast has the given symbol      */
1186 /*-----------------------------------------------------------------*/
1187 bool astHasSymbol (ast *tree, symbol *sym)
1188 {
1189     if (!tree || IS_AST_LINK(tree))
1190         return FALSE ;   
1191
1192     if (IS_AST_VALUE(tree)) {
1193         if (IS_AST_SYM_VALUE(tree)) 
1194             return isSymbolEqual(AST_SYMBOL(tree),sym);
1195         else
1196             return FALSE;
1197     }
1198     
1199     return astHasSymbol(tree->left,sym) ||
1200         astHasSymbol(tree->right,sym);
1201 }
1202
1203 /*-----------------------------------------------------------------*/
1204 /* isConformingBody - the loop body has to conform to a set of rules */
1205 /* for the loop to be considered reversible read on for rules      */
1206 /*-----------------------------------------------------------------*/
1207 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1208 {
1209     
1210     /* we are going to do a pre-order traversal of the
1211        tree && check for the following conditions. (essentially
1212        a set of very shallow tests )
1213        a) the sym passed does not participate in
1214           any arithmetic operation
1215        b) There are no function calls
1216        c) all jumps are within the body 
1217        d) address of loop control variable not taken 
1218        e) if an assignment has a pointer on the
1219           left hand side make sure right does not have
1220           loop control variable */
1221
1222     /* if we reach the end or a leaf then true */
1223     if (!pbody ||  IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1224         return TRUE ;
1225
1226
1227     /* if anything else is "volatile" */
1228     if (IS_VOLATILE(TETYPE(pbody)))
1229         return FALSE;
1230
1231     /* we will walk the body in a pre-order traversal for
1232        efficiency sake */
1233     switch (pbody->opval.op) {
1234         /*------------------------------------------------------------------*/
1235     case  '['   :       
1236         return isConformingBody (pbody->right,sym,body);
1237
1238         /*------------------------------------------------------------------*/
1239     case  PTR_OP:  
1240     case  '.'   :  
1241         return TRUE;
1242
1243         /*------------------------------------------------------------------*/
1244     case  INC_OP:  /* incerement operator unary so left only */
1245     case  DEC_OP:
1246         
1247         /* sure we are not sym is not modified */
1248         if (pbody->left                &&
1249             IS_AST_SYM_VALUE(pbody->left) &&
1250             isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1251             return FALSE;
1252
1253         if (pbody->right                &&
1254             IS_AST_SYM_VALUE(pbody->right) &&
1255             isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1256             return FALSE;
1257
1258         return TRUE;
1259
1260         /*------------------------------------------------------------------*/
1261
1262     case '*' :  /* can be unary  : if right is null then unary operation */
1263     case '+' :  
1264     case '-' :  
1265     case  '&':     
1266         
1267         /* if right is NULL then unary operation  */
1268         /*------------------------------------------------------------------*/
1269         /*----------------------------*/
1270         /*  address of                */
1271         /*----------------------------*/    
1272         if ( ! pbody->right ) { 
1273             if (IS_AST_SYM_VALUE(pbody->left) &&
1274                 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1275                 return FALSE;
1276             else
1277                 return isConformingBody(pbody->left,sym,body) ;
1278         } else {
1279             if (astHasSymbol(pbody->left,sym) ||
1280                 astHasSymbol(pbody->right,sym))
1281                 return FALSE;
1282         }
1283
1284         
1285         /*------------------------------------------------------------------*/
1286     case  '|':
1287     case  '^':
1288     case  '/':
1289     case  '%':
1290     case LEFT_OP:
1291     case RIGHT_OP:
1292         
1293         if (IS_AST_SYM_VALUE(pbody->left) &&
1294             isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1295             return FALSE ;
1296
1297         if (IS_AST_SYM_VALUE(pbody->right) &&
1298             isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1299             return FALSE ;
1300         
1301         return isConformingBody(pbody->left,sym,body) &&
1302             isConformingBody(pbody->right,sym,body);
1303         
1304     case '~' :
1305     case '!' :
1306     case RRC:
1307     case RLC:
1308     case GETHBIT:
1309         if (IS_AST_SYM_VALUE(pbody->left) &&
1310             isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1311             return FALSE;
1312         return isConformingBody (pbody->left,sym,body);
1313         
1314         /*------------------------------------------------------------------*/
1315
1316     case AND_OP:
1317     case OR_OP:
1318     case '>' :
1319     case '<' :
1320     case LE_OP:
1321     case GE_OP:
1322     case EQ_OP:
1323     case NE_OP:
1324     case '?' :
1325     case ':' :
1326     case SIZEOF:  /* evaluate wihout code generation */
1327
1328         return isConformingBody(pbody->left,sym,body) &&
1329             isConformingBody(pbody->right,sym,body);    
1330
1331         /*------------------------------------------------------------------*/
1332     case '=' :
1333
1334         /* if left has a pointer & right has loop
1335            control variable then we cannot */
1336         if (astHasPointer(pbody->left) &&
1337             astHasSymbol (pbody->right,sym))
1338             return FALSE ;
1339         if (astHasVolatile(pbody->left))
1340             return FALSE ;
1341
1342         if (IS_AST_SYM_VALUE(pbody->left) &&
1343             isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1344             return FALSE ;
1345         
1346         if (astHasVolatile(pbody->left))
1347             return FALSE;
1348
1349         return isConformingBody(pbody->left,sym,body) &&
1350             isConformingBody(pbody->right,sym,body);    
1351
1352     case MUL_ASSIGN:
1353     case DIV_ASSIGN:
1354     case AND_ASSIGN:
1355     case OR_ASSIGN:
1356     case XOR_ASSIGN:
1357     case RIGHT_ASSIGN:
1358     case LEFT_ASSIGN:
1359     case SUB_ASSIGN:
1360     case ADD_ASSIGN:
1361             assert("Parser should not have generated this\n");
1362         
1363         /*------------------------------------------------------------------*/
1364         /*----------------------------*/
1365         /*      comma operator        */
1366         /*----------------------------*/        
1367     case ',' :
1368         return isConformingBody(pbody->left,sym,body) &&
1369             isConformingBody(pbody->right,sym,body);    
1370         
1371         /*------------------------------------------------------------------*/
1372         /*----------------------------*/
1373         /*       function call        */
1374         /*----------------------------*/        
1375     case CALL:
1376         return FALSE;
1377
1378         /*------------------------------------------------------------------*/
1379         /*----------------------------*/
1380         /*     return statement       */
1381         /*----------------------------*/        
1382     case RETURN:
1383         return FALSE ;
1384
1385     case GOTO:
1386         if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1387             return TRUE ;
1388         else
1389             return FALSE;
1390     case SWITCH:
1391         if (astHasSymbol(pbody->left,sym))
1392             return FALSE ;
1393
1394     default:
1395         break;
1396     }
1397
1398     return isConformingBody(pbody->left,sym,body) &&
1399         isConformingBody(pbody->right,sym,body);        
1400         
1401     
1402
1403 }
1404
1405 /*-----------------------------------------------------------------*/
1406 /* isLoopReversible - takes a for loop as input && returns true    */
1407 /* if the for loop is reversible. If yes will set the value of     */
1408 /* the loop control var & init value & termination value           */
1409 /*-----------------------------------------------------------------*/
1410 bool isLoopReversible (ast *loop, symbol **loopCntrl, 
1411                        ast **init, ast **end )
1412 {
1413     /* if option says don't do it then don't */
1414     if (optimize.noLoopReverse)
1415         return 0;
1416     /* there are several tests to determine this */
1417        
1418     /* for loop has to be of the form 
1419        for ( <sym> = <const1> ; 
1420              [<sym> < <const2>]  ;
1421              [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1422              forBody */
1423     if (! isLoopCountable (AST_FOR(loop,initExpr),
1424                            AST_FOR(loop,condExpr),
1425                            AST_FOR(loop,loopExpr),
1426                            loopCntrl,init,end))
1427         return 0;
1428
1429     /* now do some serious checking on the body of the loop
1430      */
1431     
1432     return isConformingBody(loop->left,*loopCntrl,loop->left);
1433
1434 }
1435
1436 /*-----------------------------------------------------------------*/
1437 /* replLoopSym - replace the loop sym by loop sym -1               */
1438 /*-----------------------------------------------------------------*/
1439 static void replLoopSym ( ast *body, symbol *sym)
1440 {
1441     /* reached end */
1442     if (!body || IS_AST_LINK(body))
1443         return ;
1444
1445     if (IS_AST_SYM_VALUE(body)) {
1446         
1447         if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1448             
1449             body->type = EX_OP;
1450             body->opval.op = '-';
1451             body->left = newAst_VALUE(symbolVal(sym));
1452             body->right= newAst_VALUE(constVal("1"));
1453
1454         }
1455             
1456         return;
1457         
1458     }
1459         
1460     replLoopSym(body->left,sym);
1461     replLoopSym(body->right,sym);
1462         
1463 }
1464
1465 /*-----------------------------------------------------------------*/
1466 /* reverseLoop - do the actual loop reversal                       */
1467 /*-----------------------------------------------------------------*/
1468 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1469 {    
1470     ast *rloop ;  
1471         
1472     /* create the following tree 
1473                 <sym> = loopCount ;
1474          for_continue:
1475                 forbody
1476                 <sym> -= 1;
1477                 if (sym) goto for_continue ; 
1478                 <sym> = end - 1; */
1479     
1480     /* put it together piece by piece */
1481     rloop = newNode (NULLOP,
1482                      createIf(newAst_VALUE(symbolVal(sym)),
1483                               newNode(GOTO,
1484                                       newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1485                                       NULL),NULL),
1486                      newNode('=',
1487                              newAst_VALUE(symbolVal(sym)),
1488                              newNode('-', end,
1489                                      newAst_VALUE(constVal("1")))));
1490
1491     replLoopSym(loop->left, sym);
1492
1493     rloop = newNode(NULLOP,
1494                     newNode('=',
1495                             newAst_VALUE(symbolVal(sym)),
1496                             newNode('-',end,init)),
1497                     createLabel(AST_FOR(loop,continueLabel),
1498                                 newNode(NULLOP,
1499                                         loop->left,
1500                                         newNode(NULLOP,
1501                                                 newNode(SUB_ASSIGN,
1502                                                         newAst_VALUE(symbolVal(sym)),
1503                                                         newAst_VALUE(constVal("1"))),
1504                                                 rloop ))));
1505     
1506     return decorateType(rloop);
1507
1508 }
1509
1510 /*-----------------------------------------------------------------*/
1511 /* decorateType - compute type for this tree also does type cheking*/
1512 /*          this is done bottom up, since type have to flow upwards*/
1513 /*          it also does constant folding, and paramater checking  */
1514 /*-----------------------------------------------------------------*/
1515 ast *decorateType (ast *tree)
1516 {         
1517     int parmNumber ;
1518     link *p;
1519     
1520     if ( ! tree )
1521         return tree ;
1522     
1523     /* if already has type then do nothing */
1524     if ( tree->decorated )
1525         return tree ;
1526     
1527     tree->decorated = 1;
1528     
1529     /* print the line          */
1530     /* if not block & function */
1531     if ( tree->type == EX_OP && 
1532          ( tree->opval.op != FUNCTION  &&
1533            tree->opval.op != BLOCK     &&
1534            tree->opval.op != NULLOP    )) {
1535         filename = tree->filename ;
1536         lineno = tree->lineno ;
1537     }
1538
1539     /* if any child is an error | this one is an error do nothing */
1540     if ( tree->isError ||
1541          ( tree->left && tree->left->isError) ||
1542          ( tree->right && tree->right->isError ))
1543         return tree ;
1544
1545     /*------------------------------------------------------------------*/
1546     /*----------------------------*/
1547     /*   leaf has been reached    */
1548     /*----------------------------*/        
1549     /* if this is of type value */
1550     /* just get the type        */
1551     if ( tree->type == EX_VALUE ) {
1552         
1553         if ( IS_LITERAL(tree->opval.val->etype) ) {
1554             
1555             /* if this is a character array then declare it */
1556             if (IS_ARRAY(tree->opval.val->type))
1557                 tree->opval.val = stringToSymbol(tree->opval.val);
1558             
1559             /* otherwise just copy the type information */
1560             COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1561             return tree ;
1562         }
1563         
1564         if ( tree->opval.val->sym ) {
1565             /* if the undefined flag is set then give error message */
1566                 if (tree->opval.val->sym->undefined ) {
1567                   werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1568                   /* assume int */
1569                   TTYPE(tree) = TETYPE(tree) =
1570                     tree->opval.val->type = tree->opval.val->sym->type = 
1571                     tree->opval.val->etype = tree->opval.val->sym->etype = 
1572                     copyLinkChain(INTTYPE);
1573                 }
1574                 else {
1575                   
1576                   /* if impilicit i.e. struct/union member then no type */
1577                   if (tree->opval.val->sym->implicit )
1578                     TTYPE(tree) = TETYPE(tree) = NULL ;
1579                   
1580                   else { 
1581                     
1582                                 /* else copy the type */
1583                     COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type); 
1584                     
1585                                 /* and mark it as referenced */
1586                     tree->opval.val->sym->isref = 1;
1587                                 /* if this is of type function or function pointer */
1588                     if (funcInChain(tree->opval.val->type)) {
1589                       tree->hasVargs = tree->opval.val->sym->hasVargs;
1590                       tree->args = copyValueChain(tree->opval.val->sym->args) ;
1591                       
1592                     }
1593                   }
1594                 }
1595         }
1596         
1597         return tree ;
1598     }
1599     
1600     /* if type link for the case of cast */
1601     if ( tree->type == EX_LINK ) {
1602         COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1603         return tree ;
1604     } 
1605     
1606     {
1607         ast *dtl, *dtr;
1608         
1609         dtl = decorateType (tree->left);
1610         dtr = decorateType (tree->right);  
1611
1612         /* this is to take care of situations
1613            when the tree gets rewritten */
1614         if (dtl != tree->left)
1615             tree->left = dtl;
1616         if (dtr != tree->right)
1617             tree->right = dtr;
1618     }
1619     
1620     /* depending on type of operator do */
1621     
1622     switch   (tree->opval.op) {
1623         /*------------------------------------------------------------------*/
1624         /*----------------------------*/
1625         /*        array node          */
1626         /*----------------------------*/
1627     case  '['   :  
1628         
1629         /* determine which is the array & which the index */
1630         if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1631             
1632             ast *tempTree = tree->left ;
1633             tree->left = tree->right ;
1634             tree->right= tempTree ;
1635         }
1636
1637         /* first check if this is a array or a pointer */
1638         if ( (!IS_ARRAY(LTYPE(tree)))  && (!IS_PTR(LTYPE(tree)))) {
1639             werror(E_NEED_ARRAY_PTR,"[]");
1640             goto errorTreeReturn ;
1641         }       
1642         
1643         /* check if the type of the idx */
1644         if (!IS_INTEGRAL(RTYPE(tree))) {
1645             werror(E_IDX_NOT_INT);
1646             goto errorTreeReturn ;
1647         }
1648         
1649         /* if the left is an rvalue then error */
1650         if (LRVAL(tree)) {
1651             werror(E_LVALUE_REQUIRED,"array access");
1652             goto errorTreeReturn ;
1653         }
1654         RRVAL(tree) = 1;
1655         COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1656         return tree;
1657         
1658         /*------------------------------------------------------------------*/
1659         /*----------------------------*/
1660         /*      struct/union          */
1661         /*----------------------------*/   
1662     case  '.'   :  
1663         /* if this is not a structure */
1664         if (!IS_STRUCT(LTYPE(tree))) {
1665             werror(E_STRUCT_UNION,".");
1666             goto errorTreeReturn ;
1667         }
1668         TTYPE(tree) = structElemType (LTYPE(tree), 
1669                                       (tree->right->type == EX_VALUE ?
1670                                        tree->right->opval.val : NULL ),&tree->args);
1671         TETYPE(tree) = getSpec(TTYPE(tree));
1672         return tree ;
1673         
1674         /*------------------------------------------------------------------*/
1675         /*----------------------------*/
1676         /*    struct/union pointer    */
1677         /*----------------------------*/
1678     case  PTR_OP:  
1679         /* if not pointer to a structure */
1680         if (!IS_PTR(LTYPE(tree)))  {
1681             werror(E_PTR_REQD);
1682             goto errorTreeReturn ;
1683         }
1684         
1685         if (!IS_STRUCT(LTYPE(tree)->next))  {
1686             werror(E_STRUCT_UNION,"->");
1687             goto errorTreeReturn ;
1688         }
1689         
1690         TTYPE(tree) = structElemType (LTYPE(tree)->next, 
1691                                       (tree->right->type == EX_VALUE ?
1692                                        tree->right->opval.val : NULL ),&tree->args);
1693         TETYPE(tree) = getSpec(TTYPE(tree));
1694         return tree ;
1695         
1696         /*------------------------------------------------------------------*/
1697         /*----------------------------*/
1698         /*  ++/-- operation           */
1699         /*----------------------------*/
1700     case  INC_OP:  /* incerement operator unary so left only */
1701     case  DEC_OP:
1702         {
1703             link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1704             COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1705             if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1706                 werror(E_CODE_WRITE,"++/--");
1707             
1708             if (tree->right)
1709                 RLVAL(tree) = 1;
1710             else
1711                 LLVAL(tree) = 1;
1712             return tree ;
1713         }
1714         
1715         /*------------------------------------------------------------------*/
1716         /*----------------------------*/
1717         /*  bitwise and               */
1718         /*----------------------------*/
1719     case  '&':     /* can be unary   */
1720         /* if right is NULL then unary operation  */
1721         if ( tree->right ) /* not an unary operation */ {
1722             
1723             if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1724                 werror(E_BITWISE_OP);
1725                 werror(E_CONTINUE,"left & right types are ");
1726                 printTypeChain(LTYPE(tree),stderr);
1727                 fprintf(stderr,",");
1728                 printTypeChain(RTYPE(tree),stderr);
1729                 fprintf(stderr,"\n");
1730                 goto errorTreeReturn ;
1731             }
1732             
1733             /* if they are both literal */
1734             if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1735                 tree->type = EX_VALUE ;
1736                 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1737                                               valFromType(RETYPE(tree)),'&');
1738                                        
1739                 tree->right = tree->left = NULL;
1740                 TETYPE(tree) = tree->opval.val->etype ;
1741                 TTYPE(tree) =  tree->opval.val->type;
1742                 return tree ;
1743             }
1744             
1745             /* see if this is a GETHBIT operation if yes
1746                then return that */
1747             {
1748                 ast *otree = optimizeGetHbit(tree);
1749                 
1750                 if (otree != tree)
1751                     return decorateType(otree);
1752             }
1753             
1754             /* if right or left is literal then result of that type*/
1755             if (IS_LITERAL(RTYPE(tree))) {
1756                 
1757                 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1758                 TETYPE(tree) = getSpec(TTYPE(tree));
1759                 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1760             }
1761             else {
1762                 if (IS_LITERAL(LTYPE(tree))) {              
1763                     TTYPE(tree) = copyLinkChain(LTYPE(tree));
1764                     TETYPE(tree) = getSpec(TTYPE(tree));
1765                     SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1766                     
1767                 }
1768                 else {
1769                     TTYPE(tree) = 
1770                         computeType (LTYPE(tree), RTYPE(tree));
1771                     TETYPE(tree) = getSpec(TTYPE(tree));
1772                 }
1773             }
1774             LRVAL(tree) = RRVAL(tree) = 1;
1775             return tree ;
1776         } 
1777         
1778         /*------------------------------------------------------------------*/
1779         /*----------------------------*/
1780         /*  address of                */
1781         /*----------------------------*/    
1782         p = newLink();
1783         p->class = DECLARATOR;
1784         /* if bit field then error */
1785         if (IS_BITVAR(tree->left->etype)) {
1786             werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1787             goto errorTreeReturn ;
1788         }
1789         
1790         if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1791             werror (E_ILLEGAL_ADDR,"address of register variable");
1792             goto errorTreeReturn;
1793         }
1794         
1795         if (IS_FUNC(LTYPE(tree))) {
1796             werror(E_ILLEGAL_ADDR,"address of function");
1797             goto errorTreeReturn ;
1798         }
1799         
1800         if (LRVAL(tree)) {
1801             werror(E_LVALUE_REQUIRED,"address of");
1802             goto errorTreeReturn ;      
1803         }
1804         if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1805             DCL_TYPE(p) = CPOINTER ;
1806             DCL_PTR_CONST(p) = port->mem.code_ro;
1807         }
1808         else
1809             if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1810                 DCL_TYPE(p) = FPOINTER;
1811             else
1812                 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1813                     DCL_TYPE(p) = PPOINTER ;
1814                 else
1815                     if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1816                         DCL_TYPE(p) = IPOINTER ;
1817                     else
1818                         if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1819                             DCL_TYPE(p) = EEPPOINTER ;
1820                         else
1821                             DCL_TYPE(p) = POINTER ;
1822
1823         if (IS_AST_SYM_VALUE(tree->left)) {
1824             AST_SYMBOL(tree->left)->addrtaken = 1;
1825             AST_SYMBOL(tree->left)->allocreq = 1;
1826         }
1827
1828         p->next = LTYPE(tree);
1829         TTYPE(tree) = p;
1830         TETYPE(tree) = getSpec(TTYPE(tree));
1831         DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1832         DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1833         LLVAL(tree) = 1;
1834         TLVAL(tree) = 1;
1835         return tree ;
1836         
1837         /*------------------------------------------------------------------*/
1838         /*----------------------------*/
1839         /*  bitwise or                */
1840         /*----------------------------*/
1841     case  '|':
1842         /* if the rewrite succeeds then don't go any furthur */
1843         {
1844             ast *wtree = optimizeRRCRLC ( tree );
1845             if (wtree != tree) 
1846                 return decorateType(wtree) ;
1847         }
1848         /*------------------------------------------------------------------*/
1849         /*----------------------------*/
1850         /*  bitwise xor               */
1851         /*----------------------------*/
1852     case  '^':
1853         if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1854             werror(E_BITWISE_OP);
1855             werror(E_CONTINUE,"left & right types are ");
1856             printTypeChain(LTYPE(tree),stderr);
1857             fprintf(stderr,",");
1858             printTypeChain(RTYPE(tree),stderr);
1859             fprintf(stderr,"\n");
1860             goto errorTreeReturn ;
1861         }
1862         
1863         /* if they are both literal then */
1864         /* rewrite the tree */
1865         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1866             tree->type = EX_VALUE ;
1867             tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1868                                           valFromType(RETYPE(tree)),
1869                                           tree->opval.op);                 
1870             tree->right = tree->left = NULL;
1871             TETYPE(tree) = tree->opval.val->etype;
1872             TTYPE(tree) = tree->opval.val->type;
1873             return tree ;
1874         }
1875         LRVAL(tree) = RRVAL(tree) = 1;
1876         TETYPE(tree) = getSpec (TTYPE(tree) = 
1877                                 computeType(LTYPE(tree),
1878                                             RTYPE(tree)));
1879         
1880         /*------------------------------------------------------------------*/
1881         /*----------------------------*/
1882         /*  division                  */
1883         /*----------------------------*/
1884     case  '/':
1885         if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1886             werror(E_INVALID_OP,"divide");
1887             goto errorTreeReturn ;
1888         }
1889         /* if they are both literal then */
1890         /* rewrite the tree */
1891         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1892             tree->type = EX_VALUE ;
1893             tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1894                                       valFromType(RETYPE(tree)));
1895             tree->right = tree->left = NULL;
1896             TETYPE(tree) = getSpec(TTYPE(tree) = 
1897                                    tree->opval.val->type);
1898             return tree ;
1899         }
1900         LRVAL(tree) = RRVAL(tree) = 1;
1901         TETYPE(tree) = getSpec (TTYPE(tree) = 
1902                                 computeType(LTYPE(tree),
1903                                             RTYPE(tree)));
1904         return tree;
1905         
1906         /*------------------------------------------------------------------*/
1907         /*----------------------------*/
1908         /*            modulus         */
1909         /*----------------------------*/
1910     case  '%':
1911         if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1912             werror(E_BITWISE_OP);
1913             werror(E_CONTINUE,"left & right types are ");
1914             printTypeChain(LTYPE(tree),stderr);
1915             fprintf(stderr,",");
1916             printTypeChain(RTYPE(tree),stderr);
1917             fprintf(stderr,"\n");
1918             goto errorTreeReturn ;
1919         }
1920         /* if they are both literal then */
1921         /* rewrite the tree */
1922         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1923             tree->type = EX_VALUE ;
1924             tree->opval.val = valMod (valFromType(LETYPE(tree)),
1925                                       valFromType(RETYPE(tree)));                 
1926             tree->right = tree->left = NULL;
1927             TETYPE(tree) = getSpec(TTYPE(tree) = 
1928                                    tree->opval.val->type);
1929             return tree ;
1930         }
1931         LRVAL(tree) = RRVAL(tree) = 1;
1932         TETYPE(tree) = getSpec (TTYPE(tree) = 
1933                                 computeType(LTYPE(tree),
1934                                             RTYPE(tree)));
1935         return tree;
1936         
1937         /*------------------------------------------------------------------*/
1938         /*----------------------------*/
1939         /*  address dereference       */
1940         /*----------------------------*/
1941     case  '*':     /* can be unary  : if right is null then unary operation */
1942         if ( ! tree->right ) {
1943             if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1944                 werror(E_PTR_REQD);
1945                 goto errorTreeReturn ;
1946             }
1947             
1948             if (LRVAL(tree)) {
1949                 werror(E_LVALUE_REQUIRED,"pointer deref");
1950                 goto errorTreeReturn ;  
1951             }
1952             TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ? 
1953                                          LTYPE(tree)->next : NULL );
1954             TETYPE(tree) = getSpec(TTYPE(tree));
1955             tree->args = tree->left->args ;
1956             tree->hasVargs = tree->left->hasVargs ;
1957             SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
1958             return tree ;
1959         }
1960         
1961         /*------------------------------------------------------------------*/
1962         /*----------------------------*/
1963         /*      multiplication        */
1964         /*----------------------------*/
1965         if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1966             werror(E_INVALID_OP,"multiplication");
1967             goto errorTreeReturn ;
1968         }
1969         
1970         /* if they are both literal then */
1971         /* rewrite the tree */
1972         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1973             tree->type = EX_VALUE ;
1974             tree->opval.val = valMult (valFromType(LETYPE(tree)),
1975                                        valFromType(RETYPE(tree)));                 
1976             tree->right = tree->left = NULL;
1977             TETYPE(tree) = getSpec(TTYPE(tree) = 
1978                                    tree->opval.val->type);
1979             return tree ;
1980         }
1981
1982         /* if left is a literal exchange left & right */
1983         if (IS_LITERAL(LTYPE(tree))) {
1984             ast *tTree = tree->left ;
1985             tree->left = tree->right ;
1986             tree->right= tTree ;
1987         }
1988                 
1989         LRVAL(tree) = RRVAL(tree) = 1;
1990         TETYPE(tree) = getSpec (TTYPE(tree) = 
1991                                 computeType(LTYPE(tree),
1992                                             RTYPE(tree)));                        
1993         return tree ;
1994         
1995         /*------------------------------------------------------------------*/
1996         /*----------------------------*/
1997         /*    unary '+' operator      */
1998         /*----------------------------*/
1999     case '+' :  
2000         /* if unary plus */
2001         if ( ! tree->right ) {
2002             if (!IS_INTEGRAL(LTYPE(tree))) {
2003                 werror(E_UNARY_OP,'+');
2004                 goto errorTreeReturn ;
2005             }
2006             
2007             /* if left is a literal then do it */
2008             if (IS_LITERAL(LTYPE(tree))) {
2009                 tree->type = EX_VALUE ;
2010                 tree->opval.val = valFromType(LETYPE(tree));          
2011                 tree->left = NULL ;
2012                 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2013                 return tree ;
2014             }
2015             LRVAL(tree) = 1;
2016             COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)); 
2017             return tree ;
2018         }
2019         
2020         /*------------------------------------------------------------------*/
2021         /*----------------------------*/
2022         /*      addition              */
2023         /*----------------------------*/
2024         
2025         /* this is not a unary operation */
2026         /* if both pointers then problem */
2027         if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2028             (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2029             werror(E_PTR_PLUS_PTR);
2030             goto errorTreeReturn ;
2031         }       
2032
2033         if (!IS_ARITHMETIC(LTYPE(tree)) && 
2034             !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2035             werror(E_PLUS_INVALID,"+");
2036             goto errorTreeReturn ;
2037         }
2038         
2039         if (!IS_ARITHMETIC(RTYPE(tree)) && 
2040             !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2041             werror(E_PLUS_INVALID,"+");
2042             goto errorTreeReturn;
2043         }
2044         /* if they are both literal then */
2045         /* rewrite the tree */
2046         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2047             tree->type = EX_VALUE ;
2048             tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2049                                        valFromType(RETYPE(tree))); 
2050             tree->right = tree->left = NULL;
2051             TETYPE(tree) = getSpec(TTYPE(tree) = 
2052                                    tree->opval.val->type);
2053             return tree ;
2054         }
2055         
2056         /* if the right is a pointer or left is a literal 
2057            xchange left & right */
2058         if (IS_ARRAY(RTYPE(tree)) || 
2059             IS_PTR(RTYPE(tree))   || 
2060             IS_LITERAL(LTYPE(tree))) {
2061             ast *tTree = tree->left ;
2062             tree->left = tree->right ;
2063             tree->right= tTree ;
2064         }
2065
2066         LRVAL(tree) = RRVAL(tree) = 1;  
2067         /* if the left is a pointer */
2068         if (IS_PTR(LTYPE(tree)))      
2069             TETYPE(tree) = getSpec(TTYPE(tree) =
2070                                    LTYPE(tree));
2071         else
2072             TETYPE(tree) = getSpec(TTYPE(tree) = 
2073                                    computeType(LTYPE(tree),
2074                                                RTYPE(tree)));
2075         return tree ;
2076         
2077         /*------------------------------------------------------------------*/
2078         /*----------------------------*/
2079         /*      unary '-'             */
2080         /*----------------------------*/
2081     case '-' :  /* can be unary   */
2082         /* if right is null then unary */
2083         if ( ! tree->right ) {
2084             
2085             if (!IS_ARITHMETIC(LTYPE(tree))) {
2086                 werror(E_UNARY_OP,tree->opval.op);
2087                 goto errorTreeReturn ;
2088             }
2089             
2090             /* if left is a literal then do it */
2091             if (IS_LITERAL(LTYPE(tree))) {
2092                 tree->type = EX_VALUE ;
2093                 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2094                 tree->left = NULL ;
2095                 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2096                 return tree ;
2097             }
2098             LRVAL(tree) = 1;
2099             TTYPE(tree) =  LTYPE(tree); 
2100             return tree ;
2101         }
2102         
2103         /*------------------------------------------------------------------*/
2104         /*----------------------------*/
2105         /*    subtraction             */
2106         /*----------------------------*/
2107         
2108         if (!(IS_PTR(LTYPE(tree)) || 
2109               IS_ARRAY(LTYPE(tree)) || 
2110               IS_ARITHMETIC(LTYPE(tree)))) {
2111             werror(E_PLUS_INVALID,"-");
2112             goto errorTreeReturn ;
2113         }
2114         
2115         if (!(IS_PTR(RTYPE(tree)) || 
2116               IS_ARRAY(RTYPE(tree)) || 
2117               IS_ARITHMETIC(RTYPE(tree)))) {
2118             werror(E_PLUS_INVALID,"-");
2119             goto errorTreeReturn ;
2120         }
2121         
2122         if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2123             ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) || 
2124                IS_INTEGRAL(RTYPE(tree)))   ) {
2125             werror(E_PLUS_INVALID,"-");
2126             goto errorTreeReturn ;
2127         }
2128
2129         /* if they are both literal then */
2130         /* rewrite the tree */
2131         if (IS_LITERAL(RTYPE(tree)) &&  IS_LITERAL(LTYPE(tree))) {
2132             tree->type = EX_VALUE ;
2133             tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2134                                         valFromType(RETYPE(tree)));  
2135             tree->right = tree->left = NULL;
2136             TETYPE(tree) = getSpec(TTYPE(tree) = 
2137                                    tree->opval.val->type);
2138             return tree ;
2139         }
2140         
2141         /* if the left & right are equal then zero */
2142         if (isAstEqual(tree->left,tree->right)) {
2143             tree->type = EX_VALUE;
2144             tree->left = tree->right = NULL;
2145             tree->opval.val = constVal("0");
2146             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2147             return tree;
2148         }
2149
2150         /* if both of them are pointers or arrays then */
2151         /* the result is going to be an integer        */
2152         if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2153             ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree)))) 
2154             TETYPE(tree) = TTYPE(tree) = newIntLink();
2155         else 
2156             /* if only the left is a pointer */
2157             /* then result is a pointer      */
2158             if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) 
2159                 TETYPE(tree) = getSpec(TTYPE(tree) =
2160                                        LTYPE(tree));
2161             else
2162                 TETYPE(tree) = getSpec (TTYPE(tree) = 
2163                                         computeType(LTYPE(tree),
2164                                                     RTYPE(tree))); 
2165         LRVAL(tree) = RRVAL(tree) = 1;
2166         return tree ;  
2167         
2168         /*------------------------------------------------------------------*/
2169         /*----------------------------*/
2170         /*    compliment              */
2171         /*----------------------------*/
2172     case '~' :
2173         /* can be only integral type */
2174         if (!IS_INTEGRAL(LTYPE(tree))) {
2175             werror(E_UNARY_OP,tree->opval.op);
2176             goto errorTreeReturn ;
2177         } 
2178         
2179         /* if left is a literal then do it */
2180         if (IS_LITERAL(LTYPE(tree))) {
2181             tree->type = EX_VALUE ;
2182             tree->opval.val = valComplement(valFromType(LETYPE(tree)));     
2183             tree->left = NULL ;
2184             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2185             return tree ;
2186         }
2187         LRVAL(tree) = 1;
2188         COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2189         return tree ;
2190         
2191         /*------------------------------------------------------------------*/
2192         /*----------------------------*/
2193         /*           not              */
2194         /*----------------------------*/
2195     case '!' :
2196         /* can be pointer */
2197         if (!IS_ARITHMETIC(LTYPE(tree)) && 
2198             !IS_PTR(LTYPE(tree))        && 
2199             !IS_ARRAY(LTYPE(tree))) {
2200             werror(E_UNARY_OP,tree->opval.op);
2201             goto errorTreeReturn ;
2202         }
2203         
2204         /* if left is a literal then do it */
2205         if (IS_LITERAL(LTYPE(tree))) {
2206             tree->type = EX_VALUE ;
2207             tree->opval.val = valNot(valFromType(LETYPE(tree)));           
2208             tree->left = NULL ;
2209             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2210             return tree ;
2211         }
2212         LRVAL(tree) = 1;
2213         TTYPE(tree) = TETYPE(tree) = newCharLink();
2214         return tree ;
2215         
2216         /*------------------------------------------------------------------*/
2217         /*----------------------------*/
2218         /*           shift            */
2219         /*----------------------------*/
2220     case RRC:
2221     case RLC:
2222         TTYPE(tree) = LTYPE(tree);
2223         TETYPE(tree) = LETYPE(tree);
2224         return tree ;
2225         
2226     case GETHBIT:
2227         TTYPE(tree) = TETYPE(tree) = newCharLink();       
2228         return tree;
2229
2230     case LEFT_OP:
2231     case RIGHT_OP:
2232         if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {  
2233             werror(E_SHIFT_OP_INVALID);
2234             werror(E_CONTINUE,"left & right types are ");
2235             printTypeChain(LTYPE(tree),stderr);
2236             fprintf(stderr,",");
2237             printTypeChain(RTYPE(tree),stderr);
2238             fprintf(stderr,"\n");
2239             goto errorTreeReturn ;
2240         }
2241
2242         /* if they are both literal then */
2243         /* rewrite the tree */
2244         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2245             tree->type = EX_VALUE ;
2246             tree->opval.val = valShift (valFromType(LETYPE(tree)),
2247                                         valFromType(RETYPE(tree)),
2248                                         (tree->opval.op == LEFT_OP ? 1 : 0));             
2249             tree->right = tree->left = NULL;
2250             TETYPE(tree) = getSpec(TTYPE(tree) = 
2251                                    tree->opval.val->type);
2252             return tree ;
2253         }
2254         /* if only the right side is a literal & we are
2255            shifting more than size of the left operand then zero */
2256         if (IS_LITERAL(RTYPE(tree)) && 
2257             ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2258             (getSize(LTYPE(tree))*8)) {
2259             werror(W_SHIFT_CHANGED, 
2260                    (tree->opval.op == LEFT_OP ? "left" : "right"));
2261             tree->type = EX_VALUE;
2262             tree->left = tree->right = NULL;
2263             tree->opval.val = constVal("0");
2264             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2265             return tree;
2266         }
2267         LRVAL(tree) = RRVAL(tree) = 1;
2268         if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {          
2269             COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));     
2270         } else {
2271             COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2272         }
2273         return tree ;
2274         
2275         /*------------------------------------------------------------------*/
2276         /*----------------------------*/
2277         /*         casting            */
2278         /*----------------------------*/
2279     case CAST:  /* change the type   */
2280         /* cannot cast to an aggregate type */
2281         if (IS_AGGREGATE(LTYPE(tree))) {
2282             werror(E_CAST_ILLEGAL);
2283             goto errorTreeReturn ;
2284         }
2285         
2286         /* if the right is a literal replace the tree */
2287         if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2288             tree->type = EX_VALUE ;
2289             tree->opval.val = 
2290                 valCastLiteral(LTYPE(tree),
2291                                floatFromVal(valFromType(RETYPE(tree))));
2292             tree->left = NULL;
2293             tree->right = NULL;
2294             TTYPE(tree) = tree->opval.val->type;            
2295         }
2296         else {
2297             TTYPE(tree) = LTYPE(tree);
2298             LRVAL(tree) = 1;
2299         }
2300
2301         TETYPE(tree) = getSpec(TTYPE(tree)); 
2302         
2303         return tree;
2304         
2305         /*------------------------------------------------------------------*/
2306         /*----------------------------*/
2307         /*       logical &&, ||       */
2308         /*----------------------------*/
2309     case AND_OP:
2310     case OR_OP:
2311         /* each must me arithmetic type or be a pointer */
2312         if (!IS_PTR(LTYPE(tree)) && 
2313             !IS_ARRAY(LTYPE(tree)) && 
2314             !IS_INTEGRAL(LTYPE(tree))) {
2315             werror(E_COMPARE_OP);
2316             goto errorTreeReturn ;
2317         }
2318         
2319         if (!IS_PTR(RTYPE(tree)) &&     
2320             !IS_ARRAY(RTYPE(tree)) && 
2321             !IS_INTEGRAL(RTYPE(tree))) {
2322             werror(E_COMPARE_OP);
2323             goto errorTreeReturn ;
2324         }
2325         /* if they are both literal then */
2326         /* rewrite the tree */
2327         if (IS_LITERAL(RTYPE(tree)) &&
2328             IS_LITERAL(LTYPE(tree))) {
2329             tree->type = EX_VALUE ;
2330             tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2331                                              valFromType(RETYPE(tree)),
2332                                              tree->opval.op);               
2333             tree->right = tree->left = NULL;
2334             TETYPE(tree) = getSpec(TTYPE(tree) = 
2335                                    tree->opval.val->type);
2336             return tree ;
2337         }
2338         LRVAL(tree) = RRVAL(tree) = 1;
2339         TTYPE(tree) = TETYPE(tree) = newCharLink();
2340         return tree ;
2341         
2342         /*------------------------------------------------------------------*/
2343         /*----------------------------*/
2344         /*     comparison operators   */
2345         /*----------------------------*/    
2346     case '>' :
2347     case '<' :
2348     case LE_OP :
2349     case GE_OP :
2350     case EQ_OP :
2351     case NE_OP :
2352         {
2353             ast *lt = optimizeCompare(tree);
2354             
2355             if ( tree != lt )
2356                 return lt;
2357         }
2358
2359         /* if they are pointers they must be castable */
2360         if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2361             if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2362                 werror(E_COMPARE_OP);
2363                 fprintf(stderr,"comparing type ");
2364                 printTypeChain(LTYPE(tree),stderr);
2365                 fprintf(stderr,"to type ");
2366                 printTypeChain(RTYPE(tree),stderr);
2367                 fprintf(stderr,"\n");
2368                 goto errorTreeReturn ;
2369             }
2370         } 
2371         /* else they should be promotable to one another */
2372         else {
2373             if (!(  ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2374                     ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))))) 
2375                 
2376                 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2377                     werror(E_COMPARE_OP);
2378                     fprintf(stderr,"comparing type ");
2379                     printTypeChain(LTYPE(tree),stderr);
2380                     fprintf(stderr,"to type ");
2381                     printTypeChain(RTYPE(tree),stderr);
2382                     fprintf(stderr,"\n");
2383                     goto errorTreeReturn ;
2384                 }
2385         }
2386         
2387         /* if they are both literal then */
2388         /* rewrite the tree */
2389         if (IS_LITERAL(RTYPE(tree)) &&
2390             IS_LITERAL(LTYPE(tree))) {
2391             tree->type = EX_VALUE ;
2392             tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2393                                           valFromType(RETYPE(tree)),
2394                                           tree->opval.op);                 
2395             tree->right = tree->left = NULL;
2396             TETYPE(tree) = getSpec(TTYPE(tree) = 
2397                                    tree->opval.val->type);
2398             return tree ;
2399         }
2400         LRVAL(tree) = RRVAL(tree) = 1;
2401         TTYPE(tree) = TETYPE(tree) = newCharLink();
2402         return tree ;
2403         
2404         /*------------------------------------------------------------------*/
2405         /*----------------------------*/
2406         /*             sizeof         */
2407         /*----------------------------*/    
2408     case SIZEOF :  /* evaluate wihout code generation */
2409         /* change the type to a integer */
2410         tree->type = EX_VALUE;
2411         sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2412         tree->opval.val = constVal(buffer);
2413         tree->right = tree->left = NULL;
2414         TETYPE(tree) = getSpec(TTYPE(tree) = 
2415                                tree->opval.val->type);
2416         return tree;     
2417         
2418         /*------------------------------------------------------------------*/
2419         /*----------------------------*/
2420         /* conditional operator  '?'  */
2421         /*----------------------------*/    
2422     case '?' :
2423         /* the type is one on the left */
2424         TTYPE(tree) = LTYPE(tree);
2425         TETYPE(tree)= getSpec (TTYPE(tree));
2426         return tree ;
2427         
2428     case ':' :
2429         /* if they don't match we have a problem */
2430         if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2431             werror(E_TYPE_MISMATCH,"conditional operator"," ");
2432             goto errorTreeReturn ;
2433         }
2434         
2435         TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2436         TETYPE(tree)= getSpec(TTYPE(tree));
2437         return tree ;
2438         
2439         
2440         /*------------------------------------------------------------------*/
2441         /*----------------------------*/
2442         /*    assignment operators    */
2443         /*----------------------------*/    
2444     case MUL_ASSIGN:
2445     case DIV_ASSIGN:
2446         /* for these it must be both must be integral */
2447         if (!IS_ARITHMETIC(LTYPE(tree)) ||
2448             !IS_ARITHMETIC(RTYPE(tree))) {
2449             werror (E_OPS_INTEGRAL);
2450             goto errorTreeReturn ;
2451         }
2452         RRVAL(tree) = 1;
2453         TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2454
2455         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2456             werror(E_CODE_WRITE," ");
2457
2458         if (LRVAL(tree)) {
2459             werror(E_LVALUE_REQUIRED,"*= or /=");
2460             goto errorTreeReturn ;      
2461         }
2462         LLVAL(tree) = 1;
2463         return tree ;
2464
2465     case AND_ASSIGN:
2466     case OR_ASSIGN:
2467     case XOR_ASSIGN:
2468     case RIGHT_ASSIGN:
2469     case LEFT_ASSIGN:
2470         /* for these it must be both must be integral */
2471         if (!IS_INTEGRAL(LTYPE(tree)) ||
2472             !IS_INTEGRAL(RTYPE(tree))) {
2473             werror (E_OPS_INTEGRAL);
2474             goto errorTreeReturn ;
2475         }
2476         RRVAL(tree) = 1;
2477         TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2478
2479         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2480             werror(E_CODE_WRITE," ");
2481
2482         if (LRVAL(tree)) {
2483             werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2484             goto errorTreeReturn ;      
2485         }
2486         LLVAL(tree) = 1;
2487         return tree ;
2488         
2489         /*------------------------------------------------------------------*/
2490         /*----------------------------*/
2491         /*    -= operator             */
2492         /*----------------------------*/    
2493     case SUB_ASSIGN:
2494         if (!(IS_PTR(LTYPE(tree))   ||
2495               IS_ARITHMETIC(LTYPE(tree)))) {
2496             werror(E_PLUS_INVALID,"-=");
2497             goto errorTreeReturn ;
2498         }
2499         
2500         if (!(IS_PTR(RTYPE(tree))   ||
2501               IS_ARITHMETIC(RTYPE(tree)))) {
2502             werror(E_PLUS_INVALID,"-=");
2503             goto errorTreeReturn ;
2504         }
2505         RRVAL(tree) = 1;
2506         TETYPE(tree) = getSpec (TTYPE(tree) = 
2507                                 computeType(LTYPE(tree),
2508                                             RTYPE(tree)));  
2509
2510         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2511             werror(E_CODE_WRITE," ");
2512
2513         if (LRVAL(tree)) {
2514             werror(E_LVALUE_REQUIRED,"-=");
2515             goto errorTreeReturn ;      
2516         }
2517         LLVAL(tree) = 1;
2518         return tree;
2519         
2520         /*------------------------------------------------------------------*/
2521         /*----------------------------*/
2522         /*          += operator       */
2523         /*----------------------------*/    
2524     case ADD_ASSIGN:
2525         /* this is not a unary operation */
2526         /* if both pointers then problem */
2527         if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2528             werror(E_PTR_PLUS_PTR);
2529             goto errorTreeReturn ;
2530         }
2531         
2532         if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree)))  {
2533             werror(E_PLUS_INVALID,"+=");
2534             goto errorTreeReturn ;
2535         }
2536         
2537         if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree)))  {
2538             werror(E_PLUS_INVALID,"+=");
2539             goto errorTreeReturn;
2540         }
2541         RRVAL(tree) = 1;
2542         TETYPE(tree) = getSpec (TTYPE(tree) = 
2543                                 computeType(LTYPE(tree),
2544                                             RTYPE(tree)));  
2545
2546         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2547             werror(E_CODE_WRITE," ");
2548
2549         if (LRVAL(tree)) {
2550             werror(E_LVALUE_REQUIRED,"+=");
2551             goto errorTreeReturn ;      
2552         }
2553
2554         tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2555         tree->opval.op = '=';       
2556         return tree;
2557         
2558         /*------------------------------------------------------------------*/
2559         /*----------------------------*/
2560         /*      straight assignemnt   */
2561         /*----------------------------*/    
2562     case '=' :
2563         /* cannot be an aggregate */
2564         if (IS_AGGREGATE(LTYPE(tree))) {
2565             werror(E_AGGR_ASSIGN);
2566             goto errorTreeReturn;
2567         }
2568             
2569         /* they should either match or be castable */
2570         if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2571             werror(E_TYPE_MISMATCH,"assignment"," ");
2572             fprintf(stderr,"type --> '"); 
2573             printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2574             fprintf(stderr,"assigned to type --> '"); 
2575             printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2576             goto errorTreeReturn ;
2577         }
2578
2579         /* if the left side of the tree is of type void
2580            then report error */
2581         if (IS_VOID(LTYPE(tree))) {
2582             werror(E_CAST_ZERO);
2583             fprintf(stderr,"type --> '"); 
2584             printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2585             fprintf(stderr,"assigned to type --> '"); 
2586             printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2587         }
2588
2589         /* extra checks for pointer types */
2590         if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2591             !IS_GENPTR(LTYPE(tree))) {
2592           if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2593             werror(W_PTR_ASSIGN);
2594         }
2595
2596         TETYPE(tree) = getSpec(TTYPE(tree) = 
2597                                LTYPE(tree));
2598         RRVAL(tree) = 1;
2599         LLVAL(tree) = 1;
2600         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2601             werror(E_CODE_WRITE," ");
2602
2603         if (LRVAL(tree)) {
2604             werror(E_LVALUE_REQUIRED,"=");
2605             goto errorTreeReturn ;      
2606         }
2607
2608         return tree ;
2609         
2610         /*------------------------------------------------------------------*/
2611         /*----------------------------*/
2612         /*      comma operator        */
2613         /*----------------------------*/        
2614     case ',' :
2615         TETYPE(tree) = getSpec(TTYPE(tree) =  RTYPE(tree));
2616         return tree ;    
2617         
2618         /*------------------------------------------------------------------*/
2619         /*----------------------------*/
2620         /*       function call        */
2621         /*----------------------------*/        
2622     case CALL   :
2623         parmNumber = 1;
2624
2625
2626         if (processParms (tree->left,
2627                           tree->left->args,
2628                           tree->right,&parmNumber)) 
2629             goto errorTreeReturn ;    
2630
2631         if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2632                 tree->left->args = reverseVal(tree->left->args); 
2633                 reverseParms(tree->right);
2634         }
2635
2636         tree->args = tree->left->args ;
2637         TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2638         return tree;
2639
2640         /*------------------------------------------------------------------*/
2641         /*----------------------------*/
2642         /*     return statement       */
2643         /*----------------------------*/        
2644     case RETURN :
2645         if (!tree->right)
2646             goto voidcheck ;
2647
2648         if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2649             werror(E_RETURN_MISMATCH);
2650             goto errorTreeReturn ;
2651         }
2652
2653         if (IS_VOID(currFunc->type->next) 
2654             && tree->right && 
2655             !IS_VOID(RTYPE(tree))) {
2656             werror(E_FUNC_VOID);
2657             goto errorTreeReturn ;
2658         }
2659         
2660         /* if there is going to be a casing required then add it */
2661         if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
2662             tree->right = 
2663                 decorateType(newNode(CAST,
2664                                      newAst_LINK(copyLinkChain(currFunc->type->next)),
2665                                      tree->right));
2666         }
2667         
2668         RRVAL(tree) = 1;
2669         return tree;
2670
2671         voidcheck :
2672
2673         if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2674             werror(E_VOID_FUNC,currFunc->name);
2675             goto errorTreeReturn ;
2676         }               
2677
2678         TTYPE(tree) = TETYPE(tree) = NULL ;
2679         return tree ;    
2680
2681         /*------------------------------------------------------------------*/
2682         /*----------------------------*/
2683         /*     switch statement       */
2684         /*----------------------------*/        
2685     case SWITCH:
2686         /* the switch value must be an integer */
2687         if (!IS_INTEGRAL(LTYPE(tree))) {
2688             werror (E_SWITCH_NON_INTEGER);
2689             goto errorTreeReturn ;
2690         }
2691         LRVAL(tree) = 1;
2692         TTYPE(tree) = TETYPE(tree) = NULL ;
2693         return tree ;
2694
2695         /*------------------------------------------------------------------*/
2696         /*----------------------------*/
2697         /* ifx Statement              */
2698         /*----------------------------*/
2699     case IFX:
2700         tree->left = backPatchLabels(tree->left,
2701                                      tree->trueLabel,
2702                                      tree->falseLabel);
2703         TTYPE(tree) = TETYPE(tree) = NULL;
2704         return tree;
2705
2706         /*------------------------------------------------------------------*/
2707         /*----------------------------*/
2708         /* for Statement              */
2709         /*----------------------------*/
2710     case FOR:              
2711
2712         decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2713         decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2714         decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2715         
2716         /* if the for loop is reversible then 
2717            reverse it otherwise do what we normally
2718            do */
2719         {
2720             symbol *sym ;
2721             ast *init, *end;
2722
2723             if (isLoopReversible (tree,&sym,&init,&end))
2724                 return reverseLoop (tree,sym,init,end);
2725             else
2726                 return decorateType(createFor ( AST_FOR(tree,trueLabel), 
2727                                                 AST_FOR(tree,continueLabel) ,
2728                                                 AST_FOR(tree,falseLabel) ,
2729                                                 AST_FOR(tree,condLabel)  ,
2730                                                 AST_FOR(tree,initExpr)   , 
2731                                                 AST_FOR(tree,condExpr)   , 
2732                                                 AST_FOR(tree,loopExpr),
2733                                                 tree->left ) );
2734         }
2735     default :
2736         TTYPE(tree) = TETYPE(tree) = NULL ;
2737         return tree ;    
2738     }
2739     
2740     /* some error found this tree will be killed */
2741     errorTreeReturn :     
2742         TTYPE(tree) = TETYPE(tree) = newCharLink();
2743     tree->opval.op = NULLOP ;
2744     tree->isError = 1;
2745     
2746     return tree ;
2747 }
2748
2749 /*-----------------------------------------------------------------*/
2750 /* sizeofOp - processes size of operation                          */
2751 /*-----------------------------------------------------------------*/
2752 value  *sizeofOp( link  *type)
2753 {
2754         char buff[10];
2755
2756         /* get the size and convert it to character  */
2757         sprintf (buff,"%d", getSize(type));
2758
2759         /* now convert into value  */
2760         return  constVal (buff);      
2761 }
2762
2763
2764 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2765 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
2766 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2767 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2768 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2769 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
2770 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
2771
2772 /*-----------------------------------------------------------------*/
2773 /* backPatchLabels - change and or not operators to flow control    */
2774 /*-----------------------------------------------------------------*/
2775 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2776 {  
2777     
2778     if ( ! tree )
2779         return NULL ;
2780     
2781     if ( ! (IS_ANDORNOT(tree)))
2782         return tree ;
2783     
2784     /* if this an and */
2785     if (IS_AND(tree)) {
2786         static int localLbl = 0 ;
2787         symbol *localLabel ;
2788         
2789         sprintf (buffer,"_and_%d",localLbl++);
2790         localLabel = newSymbol(buffer,NestLevel);
2791         
2792         tree->left = backPatchLabels (tree->left, localLabel,falseLabel);    
2793         
2794         /* if left is already a IFX then just change the if true label in that */
2795         if (!IS_IFX(tree->left)) 
2796             tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2797         
2798         tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);    
2799         /* right is a IFX then just join */
2800         if (IS_IFX(tree->right))
2801             return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2802         
2803         tree->right = createLabel(localLabel,tree->right);
2804         tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2805         
2806         return newNode(NULLOP,tree->left,tree->right);
2807     }
2808     
2809     /* if this is an or operation */
2810     if (IS_OR(tree)) {
2811         static int localLbl = 0 ;
2812         symbol *localLabel ;
2813         
2814         sprintf (buffer,"_or_%d",localLbl++);
2815         localLabel = newSymbol(buffer,NestLevel);
2816         
2817         tree->left = backPatchLabels (tree->left, trueLabel,localLabel);    
2818         
2819         /* if left is already a IFX then just change the if true label in that */
2820         if (!IS_IFX(tree->left))                
2821             tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2822         
2823         tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);    
2824         /* right is a IFX then just join */
2825         if (IS_IFX(tree->right))
2826             return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2827         
2828         tree->right = createLabel(localLabel,tree->right);
2829         tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2830         
2831         return newNode(NULLOP,tree->left,tree->right);
2832     }
2833     
2834     /* change not */
2835     if (IS_NOT(tree)) {
2836         int wasnot = IS_NOT(tree->left);
2837         tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2838         
2839         /* if the left is already a IFX */
2840         if ( ! IS_IFX(tree->left) ) 
2841             tree->left = newNode (IFX,tree->left,NULL);
2842         
2843         if (wasnot) {
2844             tree->left->trueLabel = trueLabel ;
2845             tree->left->falseLabel= falseLabel ;
2846         } else {
2847             tree->left->trueLabel = falseLabel ;
2848             tree->left->falseLabel= trueLabel ;
2849         }
2850         return tree->left ;
2851     }
2852     
2853     if (IS_IFX(tree)) {
2854         tree->trueLabel = trueLabel ;
2855         tree->falseLabel= falseLabel;
2856     }
2857     
2858     return tree ;    
2859 }
2860
2861
2862 /*-----------------------------------------------------------------*/
2863 /* createBlock - create expression tree for block                  */
2864 /*-----------------------------------------------------------------*/
2865 ast  *createBlock   ( symbol *decl,   ast  *body )
2866 {
2867     ast *ex ;
2868     
2869     /* if the block has nothing */
2870     if (!body)
2871         return NULL;
2872
2873     ex = newNode(BLOCK,NULL,body);
2874     ex->values.sym = decl ;
2875     
2876     ex->right = ex->right ;
2877     ex->level++ ;
2878     ex->lineno = 0 ;
2879     return ex;
2880 }
2881
2882 /*-----------------------------------------------------------------*/
2883 /* createLabel - creates the expression tree for labels            */
2884 /*-----------------------------------------------------------------*/
2885 ast  *createLabel  ( symbol  *label,  ast  *stmnt  )
2886 {
2887     symbol *csym;
2888     char        name[SDCC_NAME_MAX+1];
2889     ast   *rValue ;
2890     
2891     /* must create fresh symbol if the symbol name  */
2892     /* exists in the symbol table, since there can  */
2893     /* be a variable with the same name as the labl */
2894     if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2895         (csym->level == label->level))
2896         label = newSymbol(label->name,label->level);
2897     
2898     /* change the name before putting it in add _*/
2899     sprintf (name,"%s",label->name);
2900     
2901     /* put the label in the LabelSymbol table    */
2902     /* but first check if a label of the same    */
2903     /* name exists                               */
2904     if ( (csym = findSym(LabelTab,NULL,name)))
2905         werror(E_DUPLICATE_LABEL,label->name);
2906     else
2907         addSym (LabelTab, label, name,label->level,0);
2908     
2909     label->islbl = 1;
2910     label->key = labelKey++ ;
2911     rValue =  newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);  
2912     rValue->lineno = 0;
2913     
2914     return rValue ;
2915 }
2916
2917 /*-----------------------------------------------------------------*/
2918 /* createCase - generates the parsetree for a case statement       */
2919 /*-----------------------------------------------------------------*/
2920 ast  *createCase (ast *swStat, ast *caseVal, ast *stmnt   )
2921 {
2922     char caseLbl[SDCC_NAME_MAX+1];
2923     ast *rexpr;
2924     value *val;
2925     
2926     /* if the switch statement does not exist */
2927     /* then case is out of context            */
2928     if (!swStat) {
2929         werror(E_CASE_CONTEXT);
2930         return NULL ;
2931     }
2932     
2933     caseVal = decorateType(resolveSymbols(caseVal));
2934     /* if not a constant then error  */
2935     if (!IS_LITERAL(caseVal->ftype)) {
2936         werror(E_CASE_CONSTANT);
2937         return NULL ;
2938     }
2939     
2940     /* if not a integer than error */
2941     if (!IS_INTEGRAL(caseVal->ftype)) {
2942         werror(E_CASE_NON_INTEGER);
2943         return NULL;
2944     }
2945
2946     /* find the end of the switch values chain   */
2947     if (!(val = swStat->values.switchVals.swVals))
2948         swStat->values.switchVals.swVals = caseVal->opval.val ;
2949     else {
2950         /* also order the cases according to value */
2951         value *pval = NULL;
2952         int cVal = (int) floatFromVal(caseVal->opval.val);
2953         while (val && (int) floatFromVal(val) < cVal) {
2954             pval = val;
2955             val = val->next ;
2956         }
2957        
2958         /* if we reached the end then */
2959         if (!val) {
2960             pval->next =  caseVal->opval.val;
2961         } else {
2962             /* we found a value greater than */
2963             /* the current value we must add this */
2964             /* before the value */
2965             caseVal->opval.val->next = val;
2966
2967             /* if this was the first in chain */
2968             if (swStat->values.switchVals.swVals == val)
2969                 swStat->values.switchVals.swVals = 
2970                     caseVal->opval.val;
2971             else
2972                 pval->next =  caseVal->opval.val;
2973         }
2974             
2975     }
2976     
2977     /* create the case label   */
2978     sprintf(caseLbl,"_case_%d_%d",
2979             swStat->values.switchVals.swNum,
2980             (int) floatFromVal(caseVal->opval.val));
2981     
2982     rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
2983     rexpr->lineno = 0;
2984     return rexpr;
2985 }
2986
2987 /*-----------------------------------------------------------------*/
2988 /* createDefault - creates the parse tree for the default statement*/
2989 /*-----------------------------------------------------------------*/
2990 ast  *createDefault (ast *swStat, ast *stmnt)
2991 {
2992     char  defLbl[SDCC_NAME_MAX+1];
2993     
2994     /* if the switch statement does not exist */
2995     /* then case is out of context            */
2996     if (!swStat) {
2997         werror(E_CASE_CONTEXT);
2998         return NULL ;
2999     }
3000     
3001     /* turn on the default flag   */
3002     swStat->values.switchVals.swDefault = 1   ;
3003     
3004     /* create the label  */
3005     sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3006     return createLabel(newSymbol(defLbl,0),stmnt);   
3007 }
3008
3009 /*-----------------------------------------------------------------*/
3010 /* createIf - creates the parsetree for the if statement           */
3011 /*-----------------------------------------------------------------*/
3012 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3013 {
3014     static int Lblnum = 0 ;
3015     ast *ifTree ;
3016     symbol *ifTrue , *ifFalse, *ifEnd ;
3017     
3018     /* if neither exists */
3019     if (! elseBody && !ifBody)
3020         return condAst ;
3021     
3022     /* create the labels */
3023     sprintf (buffer,"_iffalse_%d",Lblnum);
3024     ifFalse = newSymbol (buffer,NestLevel);
3025     /* if no else body then end == false */
3026     if ( ! elseBody ) 
3027         ifEnd = ifFalse ;
3028     else {
3029         sprintf (buffer,"_ifend_%d",Lblnum);
3030         ifEnd = newSymbol (buffer,NestLevel);
3031     }
3032
3033     sprintf (buffer,"_iftrue_%d",Lblnum);
3034     ifTrue = newSymbol (buffer,NestLevel);
3035         
3036     Lblnum++ ;
3037
3038     /* attach the ifTrue label to the top of it body */
3039     ifBody = createLabel(ifTrue,ifBody);
3040     /* attach a goto end to the ifBody if else is present */
3041     if ( elseBody ) {
3042         ifBody = newNode(NULLOP,ifBody,
3043                          newNode(GOTO,
3044                                  newAst_VALUE(symbolVal(ifEnd)),
3045                                  NULL));
3046         /* put the elseLabel on the else body */
3047         elseBody = createLabel (ifFalse,elseBody);
3048         /* out the end at the end of the body */
3049         elseBody = newNode(NULLOP,
3050                            elseBody,
3051                            createLabel(ifEnd,NULL));
3052     }
3053     else {
3054         ifBody = newNode(NULLOP,ifBody,
3055                          createLabel(ifFalse,NULL));
3056     }
3057     condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3058     if (IS_IFX(condAst))
3059         ifTree = condAst;
3060     else 
3061         ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3062     
3063     return newNode(NULLOP,ifTree,
3064                    newNode(NULLOP,ifBody,elseBody));
3065     
3066 }
3067
3068 /*-----------------------------------------------------------------*/
3069 /* createDo - creates parse tree for do                            */
3070 /*        _dobody_n:                                               */
3071 /*            statements                                           */
3072 /*        _docontinue_n:                                           */
3073 /*            condition_expression +-> trueLabel -> _dobody_n      */
3074 /*                                 |                               */
3075 /*                                 +-> falseLabel-> _dobreak_n     */
3076 /*        _dobreak_n:                                              */
3077 /*-----------------------------------------------------------------*/
3078 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3079                 symbol *falseLabel, ast *condAst, ast *doBody )
3080 {
3081     ast *doTree ;
3082     
3083     
3084     /* if the body does not exist then it is simple */
3085     if ( ! doBody ) {
3086         condAst = backPatchLabels(condAst,continueLabel,NULL);
3087         doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst) 
3088                   : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3089         doTree->trueLabel = continueLabel ;
3090         doTree->falseLabel= NULL ;
3091         return doTree ;
3092     }
3093     
3094     /* otherwise we have a body */
3095     condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3096     
3097     /* attach the body label to the top */
3098     doBody = createLabel(trueLabel,doBody);
3099     /* attach the continue label to end of body */
3100     doBody = newNode(NULLOP, doBody, 
3101                      createLabel(continueLabel,NULL));
3102     
3103     /* now put the break label at the end */
3104     if (IS_IFX(condAst))
3105         doTree = condAst;
3106     else 
3107         doTree = newIfxNode(condAst,trueLabel,falseLabel);
3108     
3109     doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3110     
3111     /* putting it together */
3112     return newNode(NULLOP,doBody,doTree);
3113 }
3114
3115 /*-----------------------------------------------------------------*/
3116 /* createFor - creates parse tree for 'for' statement              */
3117 /*        initExpr                                                 */
3118 /*   _forcond_n:                                                   */
3119 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3120 /*                  |                                              */
3121 /*                  +-> falseLabel-> _forbreak_n                   */
3122 /*   _forbody_n:                                                   */
3123 /*        statements                                               */
3124 /*   _forcontinue_n:                                               */
3125 /*        loopExpr                                                 */
3126 /*        goto _forcond_n ;                                        */
3127 /*   _forbreak_n:                                                  */
3128 /*-----------------------------------------------------------------*/
3129 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3130                  symbol *falseLabel,symbol *condLabel     ,
3131                  ast *initExpr, ast *condExpr, ast *loopExpr,
3132                  ast *forBody )
3133 {
3134     ast *forTree ;      
3135
3136     /* if loopexpression not present then we can generate it */
3137     /* the same way as a while */
3138     if ( ! loopExpr ) 
3139         return newNode(NULLOP,initExpr,
3140                        createWhile (trueLabel, continueLabel, 
3141                                     falseLabel,condExpr, forBody ));
3142     /* vanilla for statement */
3143     condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3144     
3145     if (condExpr && !IS_IFX(condExpr)) 
3146         condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3147     
3148     
3149     /* attach condition label to condition */
3150     condExpr = createLabel(condLabel,condExpr);
3151     
3152     /* attach body label to body */
3153     forBody = createLabel(trueLabel,forBody);
3154     
3155     /* attach continue to forLoop expression & attach */
3156     /* goto the forcond @ and of loopExpression       */
3157     loopExpr = createLabel(continueLabel,
3158                            newNode(NULLOP,
3159                                    loopExpr,
3160                                    newNode(GOTO,
3161                                            newAst_VALUE(symbolVal(condLabel)),
3162                                            NULL)));
3163     /* now start putting them together */
3164     forTree = newNode(NULLOP,initExpr,condExpr);
3165     forTree = newNode(NULLOP,forTree,forBody);
3166     forTree = newNode(NULLOP,forTree,loopExpr);
3167     /* finally add the break label */
3168     forTree = newNode(NULLOP,forTree,
3169                       createLabel(falseLabel,NULL));
3170     return forTree ;
3171 }
3172
3173 /*-----------------------------------------------------------------*/
3174 /* createWhile - creates parse tree for while statement            */
3175 /*               the while statement will be created as follows    */
3176 /*                                                                 */
3177 /*      _while_continue_n:                                         */
3178 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3179 /*                                 |                               */
3180 /*                                 +-> falseLabel -> _while_break_n*/
3181 /*      _while_body_n:                                             */
3182 /*            statements                                           */
3183 /*            goto _while_continue_n                               */
3184 /*      _while_break_n:                                            */
3185 /*-----------------------------------------------------------------*/
3186 ast *createWhile (symbol *trueLabel, symbol *continueLabel, 
3187                    symbol *falseLabel,ast *condExpr, ast *whileBody )
3188 {
3189     ast *whileTree ;
3190         
3191     /* put the continue label */
3192     condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3193     condExpr = createLabel(continueLabel,condExpr);
3194     condExpr->lineno = 0;
3195     
3196     /* put the body label in front of the body */
3197     whileBody = createLabel(trueLabel,whileBody);
3198     whileBody->lineno = 0;
3199     /* put a jump to continue at the end of the body */
3200     /* and put break label at the end of the body */
3201     whileBody = newNode(NULLOP,
3202                         whileBody,
3203                         newNode(GOTO,
3204                                 newAst_VALUE(symbolVal(continueLabel)),
3205                                 createLabel(falseLabel,NULL)));
3206     
3207     /* put it all together */
3208     if ( IS_IFX(condExpr) )
3209         whileTree = condExpr ;
3210     else {
3211         whileTree = newNode (IFX, condExpr,NULL );      
3212         /* put the true & false labels in place */
3213         whileTree->trueLabel = trueLabel ;
3214         whileTree->falseLabel= falseLabel;
3215     }
3216     
3217     return newNode(NULLOP,whileTree,whileBody );
3218 }
3219
3220 /*-----------------------------------------------------------------*/
3221 /* optimizeGetHbit - get highest order bit of the expression       */
3222 /*-----------------------------------------------------------------*/
3223 ast *optimizeGetHbit (ast *tree)
3224 {
3225     int i,j;
3226     /* if this is not a bit and */
3227     if (!IS_BITAND(tree))
3228         return tree;
3229     
3230     /* will look for tree of the form
3231        ( expr >> ((sizeof expr) -1) ) & 1 */
3232     if (!IS_AST_LIT_VALUE(tree->right))
3233         return tree;
3234
3235     if (AST_LIT_VALUE(tree->right) != 1)
3236         return tree;
3237
3238     if (!IS_RIGHT_OP(tree->left))
3239         return tree;
3240
3241     if (!IS_AST_LIT_VALUE(tree->left->right))
3242         return tree;
3243
3244     if ((i = AST_LIT_VALUE(tree->left->right)) !=
3245         ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3246         return tree;
3247
3248     return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3249         
3250 }
3251
3252 /*-----------------------------------------------------------------*/
3253 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3254 /*-----------------------------------------------------------------*/
3255 ast *optimizeRRCRLC ( ast *root )
3256 {
3257     /* will look for trees of the form
3258        (?expr << 1) | (?expr >> 7) or
3259        (?expr >> 7) | (?expr << 1) will make that
3260        into a RLC : operation ..
3261        Will also look for 
3262        (?expr >> 1) | (?expr << 7) or
3263        (?expr << 7) | (?expr >> 1) will make that
3264        into a RRC operation 
3265        note : by 7 I mean (number of bits required to hold the
3266        variable -1 ) */
3267     /* if the root operations is not a | operation the not */
3268     if (!IS_BITOR(root))
3269         return root ;
3270
3271     /* I have to think of a better way to match patterns this sucks */
3272     /* that aside let start looking for the first case : I use a the
3273        negative check a lot to improve the efficiency */
3274     /* (?expr << 1) | (?expr >> 7) */
3275     if (IS_LEFT_OP(root->left)    && 
3276         IS_RIGHT_OP(root->right)  ) {   
3277         
3278         if (!SPEC_USIGN(TETYPE(root->left->left)))
3279             return root;
3280
3281         if (!IS_AST_LIT_VALUE(root->left->right) ||
3282             !IS_AST_LIT_VALUE(root->right->right))
3283             goto tryNext0;
3284
3285         /* make sure it is the same expression */
3286         if (!isAstEqual(root->left->left,
3287                         root->right->left))
3288             goto tryNext0;
3289         
3290         if (AST_LIT_VALUE(root->left->right) != 1 )
3291             goto tryNext0 ;
3292         
3293         if (AST_LIT_VALUE(root->right->right) !=
3294             (getSize(TTYPE(root->left->left))*8 - 1))
3295             goto tryNext0 ;
3296
3297         /* whew got the first case : create the AST */
3298         return  newNode(RLC,root->left->left,NULL);     
3299     }
3300
3301  tryNext0:
3302     /* check for second case */
3303     /* (?expr >> 7) | (?expr << 1) */
3304     if (IS_LEFT_OP(root->right)    && 
3305         IS_RIGHT_OP(root->left)  ) {     
3306
3307         if (!SPEC_USIGN(TETYPE(root->left->left)))
3308             return root;
3309         
3310         if (!IS_AST_LIT_VALUE(root->left->right) ||
3311             !IS_AST_LIT_VALUE(root->right->right))
3312             goto tryNext1 ;
3313         
3314         /* make sure it is the same symbol */
3315         if (!isAstEqual(root->left->left,
3316                         root->right->left))
3317             goto tryNext1 ;
3318         
3319         if (AST_LIT_VALUE(root->right->right) != 1 )
3320             goto tryNext1 ;
3321         
3322         if (AST_LIT_VALUE(root->left->right) !=
3323             (getSize(TTYPE(root->left->left))*8 - 1))
3324             goto tryNext1 ;
3325
3326         /* whew got the first case : create the AST */
3327         return  newNode(RLC,root->left->left,NULL);
3328         
3329     }
3330
3331  tryNext1:
3332     /* third case for RRC */
3333     /*  (?symbol >> 1) | (?symbol << 7) */
3334     if (IS_LEFT_OP(root->right)    && 
3335         IS_RIGHT_OP(root->left)  ) {    
3336
3337         if (!SPEC_USIGN(TETYPE(root->left->left)))
3338             return root;
3339         
3340         if (!IS_AST_LIT_VALUE(root->left->right) ||
3341             !IS_AST_LIT_VALUE(root->right->right))
3342             goto tryNext2;
3343         
3344         /* make sure it is the same symbol */
3345         if (!isAstEqual(root->left->left,
3346                         root->right->left))
3347             goto tryNext2;
3348         
3349         if (AST_LIT_VALUE(root->left->right) != 1 )
3350             goto tryNext2;
3351         
3352         if (AST_LIT_VALUE(root->right->right) !=
3353             (getSize(TTYPE(root->left->left))*8 - 1))
3354             goto tryNext2;
3355
3356         /* whew got the first case : create the AST */
3357         return newNode(RRC,root->left->left,NULL);
3358         
3359     }
3360  tryNext2:
3361     /* fourth and last case for now */
3362     /* (?symbol << 7) | (?symbol >> 1) */
3363     if (IS_RIGHT_OP(root->right)    && 
3364         IS_LEFT_OP(root->left)  ) {     
3365
3366         if (!SPEC_USIGN(TETYPE(root->left->left)))
3367             return root;
3368         
3369         if (!IS_AST_LIT_VALUE(root->left->right) ||
3370             !IS_AST_LIT_VALUE(root->right->right))
3371             return root;
3372
3373         /* make sure it is the same symbol */
3374         if (!isAstEqual(root->left->left,
3375                         root->right->left))
3376             return root;
3377         
3378         if (AST_LIT_VALUE(root->right->right) != 1 )
3379             return root ;
3380         
3381         if (AST_LIT_VALUE(root->left->right) !=
3382             (getSize(TTYPE(root->left->left))*8 - 1))
3383             return root ;
3384
3385         /* whew got the first case : create the AST */
3386         return  newNode(RRC,root->left->left,NULL);
3387         
3388     }
3389
3390     /* not found return root */
3391     return root;
3392 }
3393
3394 /*-----------------------------------------------------------------*/
3395 /* optimizeCompare - otimizes compares for bit variables           */
3396 /*-----------------------------------------------------------------*/
3397 ast  *optimizeCompare ( ast *root )
3398 {
3399     ast *optExpr = NULL;
3400     value       *vleft;
3401     value       *vright;
3402     unsigned int litValue ;
3403     
3404     /* if nothing then return nothing */
3405     if (!root)
3406         return NULL ;
3407     
3408     /* if not a compare op then do leaves */
3409     if (!IS_COMPARE_OP(root)) {
3410         root->left = optimizeCompare (root->left);
3411         root->right= optimizeCompare (root->right);
3412         return root ;
3413     }
3414     
3415     /* if left & right are the same then depending 
3416        of the operation do */
3417     if (isAstEqual(root->left,root->right)) {
3418         switch (root->opval.op) {
3419         case '>' :
3420         case '<' :
3421         case NE_OP :
3422             optExpr = newAst_VALUE(constVal("0"));
3423             break;
3424         case GE_OP :
3425         case LE_OP :
3426         case EQ_OP :
3427             optExpr = newAst_VALUE(constVal("1"));
3428             break;
3429         }
3430
3431         return decorateType(optExpr);
3432     }
3433
3434     vleft = (root->left->type == EX_VALUE ?
3435              root->left->opval.val : NULL );
3436     
3437     vright = (root->right->type == EX_VALUE ?
3438               root->right->opval.val : NULL);
3439     
3440     /* if left is a BITVAR in BITSPACE */
3441     /* and right is a LITERAL then opt-*/
3442     /* imize else do nothing               */
3443     if (vleft && vright                   &&
3444         IS_BITVAR(vleft->etype)           && 
3445         IN_BITSPACE(SPEC_OCLS(vleft->etype))  &&
3446         IS_LITERAL(vright->etype)) {
3447         
3448         /* if right side > 1 then comparison may never succeed */
3449         if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3450             werror(W_BAD_COMPARE);
3451             goto noOptimize ;
3452         }
3453         
3454         if ( litValue ) {
3455             switch (root->opval.op) {
3456             case '>' :  /* bit value greater than 1 cannot be */
3457                 werror(W_BAD_COMPARE);
3458                 goto noOptimize ;
3459                 break;
3460                 
3461             case '<' : /* bit value < 1 means 0 */
3462             case NE_OP :
3463                 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3464                 break;
3465                 
3466             case LE_OP : /* bit value <= 1 means no check */
3467                 optExpr = newAst_VALUE(vright);         
3468                 break;
3469                 
3470             case GE_OP : /* bit value >= 1 means only check for = */
3471             case EQ_OP :
3472                 optExpr = newAst_VALUE(vleft);          
3473                 break;
3474             }
3475         } else { /* literal is zero */
3476             switch (root->opval.op) {
3477             case '<' :  /* bit value < 0 cannot be */
3478                 werror(W_BAD_COMPARE);
3479                 goto noOptimize ;
3480                 break;
3481                 
3482             case '>' : /* bit value > 0 means 1 */
3483             case NE_OP :
3484                 optExpr = newAst_VALUE(vleft);       
3485                 break;
3486                 
3487             case LE_OP : /* bit value <= 0 means no check */
3488             case GE_OP : /* bit value >= 0 means no check */
3489                 werror(W_BAD_COMPARE);
3490                 goto noOptimize ;
3491                 break;
3492                 
3493             case EQ_OP : /* bit == 0 means ! of bit */
3494                 optExpr = newNode('!',newAst_VALUE(vleft),NULL);              
3495                 break;
3496             }
3497         }                      
3498         return decorateType(resolveSymbols(optExpr)); 
3499     }   /* end-of-if of BITVAR */
3500     
3501     noOptimize :
3502         return root;
3503 }
3504 /*-----------------------------------------------------------------*/
3505 /* addSymToBlock : adds the symbol to the first block we find      */
3506 /*-----------------------------------------------------------------*/
3507 void addSymToBlock (symbol *sym, ast *tree)
3508 {
3509     /* reached end of tree or a leaf */
3510     if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3511         return ;
3512
3513     /* found a block */
3514     if (IS_AST_OP(tree) &&
3515         tree->opval.op == BLOCK ) {
3516         
3517         symbol *lsym = copySymbol(sym);
3518         
3519         lsym->next = AST_VALUES(tree,sym);
3520         AST_VALUES(tree,sym) = lsym ;
3521         return ;
3522     }
3523     
3524     addSymToBlock(sym,tree->left);
3525     addSymToBlock(sym,tree->right);
3526 }
3527
3528 /*-----------------------------------------------------------------*/
3529 /* processRegParms - do processing for register parameters         */
3530 /*-----------------------------------------------------------------*/
3531 static void processRegParms (value *args, ast *body)
3532 {
3533     while (args) {
3534         if (IS_REGPARM(args->etype))
3535             addSymToBlock(args->sym,body);
3536         args = args->next;
3537     }
3538 }
3539
3540 /*-----------------------------------------------------------------*/
3541 /* resetParmKey - resets the operandkeys for the symbols           */
3542 /*-----------------------------------------------------------------*/
3543 DEFSETFUNC(resetParmKey)
3544 {
3545     symbol *sym = item;
3546
3547     sym->key = 0 ;
3548     sym->defs = NULL ;
3549     sym->uses = NULL ;
3550     sym->remat= 0;
3551     return 1;
3552 }
3553
3554 /*-----------------------------------------------------------------*/
3555 /* createFunction - This is the key node that calls the iCode for  */
3556 /*                  generating the code for a function. Note code  */
3557 /*                  is generated function by function, later when  */
3558 /*                  add inter-procedural analysis this will change */
3559 /*-----------------------------------------------------------------*/
3560 ast  *createFunction   (symbol  *name,   ast  *body )
3561 {
3562     ast  *ex ;
3563     symbol *csym;
3564     int stack = 0 ;
3565     link *fetype;       
3566     iCode *piCode = NULL;
3567     
3568     /* if check function return 0 then some problem */
3569     if (checkFunction (name) == 0)
3570         return NULL;
3571     
3572     /* create a dummy block if none exists */
3573     if (!body)
3574         body = newNode(BLOCK,NULL,NULL);
3575
3576     noLineno++ ;
3577    
3578     /* check if the function name already in the symbol table */
3579     if ((csym = findSym (SymbolTab,NULL,name->name))) {
3580         name = csym ;     
3581         /* special case for compiler defined functions
3582            we need to add the name to the publics list : this
3583            actually means we are now compiling the compiler
3584            support routine */
3585         if (name->cdef) {
3586             addSet(&publics,name);
3587         }
3588     }
3589     else {
3590         addSymChain(name);
3591         allocVariables(name);
3592     }
3593     name->lastLine = yylineno;
3594     currFunc = name ;
3595     processFuncArgs(currFunc,0);
3596     
3597     /* set the stack pointer */
3598     /* PENDING: check this for the mcs51 */
3599     stackPtr = -port->stack.direction * port->stack.call_overhead;
3600     if (IS_ISR(name->etype))
3601         stackPtr -= port->stack.direction * port->stack.isr_overhead;
3602     if (IS_RENT(name->etype) || options.stackAuto)
3603         stackPtr -= port->stack.direction * port->stack.reent_overhead;
3604
3605     xstackPtr = -port->stack.direction * port->stack.call_overhead;
3606     
3607     fetype = getSpec(name->type); /* get the specifier for the function */
3608     /* if this is a reentrant function then */
3609     if (IS_RENT(fetype))
3610         reentrant++ ;
3611         
3612     allocParms (name->args);           /* allocate the parameters */
3613
3614     /* do processing for parameters that are passed in registers */
3615     processRegParms (name->args,body); 
3616
3617    /* set the stack pointer */
3618     stackPtr = 0;
3619     xstackPtr= -1;
3620     
3621     /* allocate & autoinit the block variables */
3622     processBlockVars (body, &stack,ALLOCATE); 
3623     
3624     /* save the stack information */
3625     if (options.useXstack)
3626         name->xstack = SPEC_STAK(fetype) = stack;
3627     else
3628         name->stack = SPEC_STAK(fetype) = stack;
3629     
3630     /* name needs to be mangled */
3631     sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3632     
3633     body = resolveSymbols(body); /* resolve the symbols */
3634     body = decorateType (body);  /* propagateType & do semantic checks */
3635     
3636     ex = newAst_VALUE(symbolVal(name));    /* create name       */
3637     ex = newNode (FUNCTION,ex,body);
3638     ex->values.args = name->args ;
3639     
3640     if (fatalError) {
3641         werror(E_FUNC_NO_CODE,name->name);
3642         goto skipall ;
3643     }
3644         
3645     /* create the node & generate intermediate code */  
3646     codeOutFile = code->oFile;
3647     piCode = iCodeFromAst(ex);
3648
3649      if (fatalError) {
3650          werror(E_FUNC_NO_CODE,name->name);
3651          goto skipall ;
3652      }
3653      
3654      eBBlockFromiCode(piCode);
3655                     
3656     /* if there are any statics then do them */
3657     if (staticAutos) {
3658         codeOutFile = statsg->oFile;
3659         eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3660         staticAutos = NULL;
3661     }
3662     
3663  skipall:
3664     
3665     /* dealloc the block variables */
3666     processBlockVars(body, &stack,DEALLOCATE);
3667     /* deallocate paramaters */
3668     deallocParms(name->args);
3669     
3670     if (IS_RENT(fetype))
3671         reentrant-- ;
3672     
3673     /* we are done freeup memory & cleanup */
3674     noLineno-- ;
3675     labelKey = 1 ;
3676     name->key = 0;
3677     name->fbody = 1;
3678     addSet(&operKeyReset,name);
3679     applyToSet(operKeyReset,resetParmKey);
3680        
3681     if (options.debug && !options.nodebug)
3682         cdbStructBlock(1,cdbFile);
3683
3684     cleanUpLevel(LabelTab,0);
3685     cleanUpBlock(StructTab,1);
3686     cleanUpBlock(TypedefTab,1);
3687
3688     xstack->syms = NULL;
3689     istack->syms = NULL;
3690     return NULL ;
3691 }
3692
3693