Fixed some BITFIELD related problems
[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             if (funcInChain(tree->opval.val->type)) {
1562                     tree->hasVargs = tree->opval.val->sym->hasVargs;
1563                     tree->args = copyValueChain(tree->opval.val->sym->args) ;
1564             }
1565             return tree ;
1566         }
1567         
1568         if ( tree->opval.val->sym ) {
1569             /* if the undefined flag is set then give error message */
1570                 if (tree->opval.val->sym->undefined ) {
1571                   werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1572                   /* assume int */
1573                   TTYPE(tree) = TETYPE(tree) =
1574                     tree->opval.val->type = tree->opval.val->sym->type = 
1575                     tree->opval.val->etype = tree->opval.val->sym->etype = 
1576                     copyLinkChain(INTTYPE);
1577                 }
1578                 else {
1579                   
1580                   /* if impilicit i.e. struct/union member then no type */
1581                   if (tree->opval.val->sym->implicit )
1582                     TTYPE(tree) = TETYPE(tree) = NULL ;
1583                   
1584                   else { 
1585                     
1586                                 /* else copy the type */
1587                     COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type); 
1588                     
1589                                 /* and mark it as referenced */
1590                     tree->opval.val->sym->isref = 1;
1591                                 /* if this is of type function or function pointer */
1592                     if (funcInChain(tree->opval.val->type)) {
1593                       tree->hasVargs = tree->opval.val->sym->hasVargs;
1594                       tree->args = copyValueChain(tree->opval.val->sym->args) ;
1595                       
1596                     }
1597                   }
1598                 }
1599         }
1600         
1601         return tree ;
1602     }
1603     
1604     /* if type link for the case of cast */
1605     if ( tree->type == EX_LINK ) {
1606         COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1607         return tree ;
1608     } 
1609     
1610     {
1611         ast *dtl, *dtr;
1612         
1613         dtl = decorateType (tree->left);
1614         dtr = decorateType (tree->right);  
1615
1616         /* this is to take care of situations
1617            when the tree gets rewritten */
1618         if (dtl != tree->left)
1619             tree->left = dtl;
1620         if (dtr != tree->right)
1621             tree->right = dtr;
1622     }
1623     
1624     /* depending on type of operator do */
1625     
1626     switch   (tree->opval.op) {
1627         /*------------------------------------------------------------------*/
1628         /*----------------------------*/
1629         /*        array node          */
1630         /*----------------------------*/
1631     case  '['   :  
1632         
1633         /* determine which is the array & which the index */
1634         if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1635             
1636             ast *tempTree = tree->left ;
1637             tree->left = tree->right ;
1638             tree->right= tempTree ;
1639         }
1640
1641         /* first check if this is a array or a pointer */
1642         if ( (!IS_ARRAY(LTYPE(tree)))  && (!IS_PTR(LTYPE(tree)))) {
1643             werror(E_NEED_ARRAY_PTR,"[]");
1644             goto errorTreeReturn ;
1645         }       
1646         
1647         /* check if the type of the idx */
1648         if (!IS_INTEGRAL(RTYPE(tree))) {
1649             werror(E_IDX_NOT_INT);
1650             goto errorTreeReturn ;
1651         }
1652         
1653         /* if the left is an rvalue then error */
1654         if (LRVAL(tree)) {
1655             werror(E_LVALUE_REQUIRED,"array access");
1656             goto errorTreeReturn ;
1657         }
1658         RRVAL(tree) = 1;
1659         COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1660         return tree;
1661         
1662         /*------------------------------------------------------------------*/
1663         /*----------------------------*/
1664         /*      struct/union          */
1665         /*----------------------------*/   
1666     case  '.'   :  
1667         /* if this is not a structure */
1668         if (!IS_STRUCT(LTYPE(tree))) {
1669             werror(E_STRUCT_UNION,".");
1670             goto errorTreeReturn ;
1671         }
1672         TTYPE(tree) = structElemType (LTYPE(tree), 
1673                                       (tree->right->type == EX_VALUE ?
1674                                        tree->right->opval.val : NULL ),&tree->args);
1675         TETYPE(tree) = getSpec(TTYPE(tree));
1676         return tree ;
1677         
1678         /*------------------------------------------------------------------*/
1679         /*----------------------------*/
1680         /*    struct/union pointer    */
1681         /*----------------------------*/
1682     case  PTR_OP:  
1683         /* if not pointer to a structure */
1684         if (!IS_PTR(LTYPE(tree)))  {
1685             werror(E_PTR_REQD);
1686             goto errorTreeReturn ;
1687         }
1688         
1689         if (!IS_STRUCT(LTYPE(tree)->next))  {
1690             werror(E_STRUCT_UNION,"->");
1691             goto errorTreeReturn ;
1692         }
1693         
1694         TTYPE(tree) = structElemType (LTYPE(tree)->next, 
1695                                       (tree->right->type == EX_VALUE ?
1696                                        tree->right->opval.val : NULL ),&tree->args);
1697         TETYPE(tree) = getSpec(TTYPE(tree));
1698         return tree ;
1699         
1700         /*------------------------------------------------------------------*/
1701         /*----------------------------*/
1702         /*  ++/-- operation           */
1703         /*----------------------------*/
1704     case  INC_OP:  /* incerement operator unary so left only */
1705     case  DEC_OP:
1706         {
1707             link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1708             COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1709             if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1710                 werror(E_CODE_WRITE,"++/--");
1711             
1712             if (tree->right)
1713                 RLVAL(tree) = 1;
1714             else
1715                 LLVAL(tree) = 1;
1716             return tree ;
1717         }
1718         
1719         /*------------------------------------------------------------------*/
1720         /*----------------------------*/
1721         /*  bitwise and               */
1722         /*----------------------------*/
1723     case  '&':     /* can be unary   */
1724         /* if right is NULL then unary operation  */
1725         if ( tree->right ) /* not an unary operation */ {
1726             
1727             if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1728                 werror(E_BITWISE_OP);
1729                 werror(E_CONTINUE,"left & right types are ");
1730                 printTypeChain(LTYPE(tree),stderr);
1731                 fprintf(stderr,",");
1732                 printTypeChain(RTYPE(tree),stderr);
1733                 fprintf(stderr,"\n");
1734                 goto errorTreeReturn ;
1735             }
1736             
1737             /* if they are both literal */
1738             if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1739                 tree->type = EX_VALUE ;
1740                 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1741                                               valFromType(RETYPE(tree)),'&');
1742                                        
1743                 tree->right = tree->left = NULL;
1744                 TETYPE(tree) = tree->opval.val->etype ;
1745                 TTYPE(tree) =  tree->opval.val->type;
1746                 return tree ;
1747             }
1748             
1749             /* see if this is a GETHBIT operation if yes
1750                then return that */
1751             {
1752                 ast *otree = optimizeGetHbit(tree);
1753                 
1754                 if (otree != tree)
1755                     return decorateType(otree);
1756             }
1757             
1758             /* if right or left is literal then result of that type*/
1759             if (IS_LITERAL(RTYPE(tree))) {
1760                 
1761                 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1762                 TETYPE(tree) = getSpec(TTYPE(tree));
1763                 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1764             }
1765             else {
1766                 if (IS_LITERAL(LTYPE(tree))) {              
1767                     TTYPE(tree) = copyLinkChain(LTYPE(tree));
1768                     TETYPE(tree) = getSpec(TTYPE(tree));
1769                     SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1770                     
1771                 }
1772                 else {
1773                     TTYPE(tree) = 
1774                         computeType (LTYPE(tree), RTYPE(tree));
1775                     TETYPE(tree) = getSpec(TTYPE(tree));
1776                 }
1777             }
1778             LRVAL(tree) = RRVAL(tree) = 1;
1779             return tree ;
1780         } 
1781         
1782         /*------------------------------------------------------------------*/
1783         /*----------------------------*/
1784         /*  address of                */
1785         /*----------------------------*/    
1786         p = newLink();
1787         p->class = DECLARATOR;
1788         /* if bit field then error */
1789         if (IS_BITVAR(tree->left->etype)) {
1790             werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1791             goto errorTreeReturn ;
1792         }
1793         
1794         if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1795             werror (E_ILLEGAL_ADDR,"address of register variable");
1796             goto errorTreeReturn;
1797         }
1798         
1799         if (IS_FUNC(LTYPE(tree))) {
1800             werror(E_ILLEGAL_ADDR,"address of function");
1801             goto errorTreeReturn ;
1802         }
1803         
1804         if (LRVAL(tree)) {
1805             werror(E_LVALUE_REQUIRED,"address of");
1806             goto errorTreeReturn ;      
1807         }
1808         if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1809             DCL_TYPE(p) = CPOINTER ;
1810             DCL_PTR_CONST(p) = port->mem.code_ro;
1811         }
1812         else
1813             if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1814                 DCL_TYPE(p) = FPOINTER;
1815             else
1816                 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1817                     DCL_TYPE(p) = PPOINTER ;
1818                 else
1819                     if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1820                         DCL_TYPE(p) = IPOINTER ;
1821                     else
1822                         if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1823                             DCL_TYPE(p) = EEPPOINTER ;
1824                         else
1825                             DCL_TYPE(p) = POINTER ;
1826
1827         if (IS_AST_SYM_VALUE(tree->left)) {
1828             AST_SYMBOL(tree->left)->addrtaken = 1;
1829             AST_SYMBOL(tree->left)->allocreq = 1;
1830         }
1831
1832         p->next = LTYPE(tree);
1833         TTYPE(tree) = p;
1834         TETYPE(tree) = getSpec(TTYPE(tree));
1835         DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1836         DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1837         LLVAL(tree) = 1;
1838         TLVAL(tree) = 1;
1839         return tree ;
1840         
1841         /*------------------------------------------------------------------*/
1842         /*----------------------------*/
1843         /*  bitwise or                */
1844         /*----------------------------*/
1845     case  '|':
1846         /* if the rewrite succeeds then don't go any furthur */
1847         {
1848             ast *wtree = optimizeRRCRLC ( tree );
1849             if (wtree != tree) 
1850                 return decorateType(wtree) ;
1851         }
1852         /*------------------------------------------------------------------*/
1853         /*----------------------------*/
1854         /*  bitwise xor               */
1855         /*----------------------------*/
1856     case  '^':
1857         if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1858             werror(E_BITWISE_OP);
1859             werror(E_CONTINUE,"left & right types are ");
1860             printTypeChain(LTYPE(tree),stderr);
1861             fprintf(stderr,",");
1862             printTypeChain(RTYPE(tree),stderr);
1863             fprintf(stderr,"\n");
1864             goto errorTreeReturn ;
1865         }
1866         
1867         /* if they are both literal then */
1868         /* rewrite the tree */
1869         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1870             tree->type = EX_VALUE ;
1871             tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1872                                           valFromType(RETYPE(tree)),
1873                                           tree->opval.op);                 
1874             tree->right = tree->left = NULL;
1875             TETYPE(tree) = tree->opval.val->etype;
1876             TTYPE(tree) = tree->opval.val->type;
1877             return tree ;
1878         }
1879         LRVAL(tree) = RRVAL(tree) = 1;
1880         TETYPE(tree) = getSpec (TTYPE(tree) = 
1881                                 computeType(LTYPE(tree),
1882                                             RTYPE(tree)));
1883         
1884         /*------------------------------------------------------------------*/
1885         /*----------------------------*/
1886         /*  division                  */
1887         /*----------------------------*/
1888     case  '/':
1889         if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1890             werror(E_INVALID_OP,"divide");
1891             goto errorTreeReturn ;
1892         }
1893         /* if they are both literal then */
1894         /* rewrite the tree */
1895         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1896             tree->type = EX_VALUE ;
1897             tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1898                                       valFromType(RETYPE(tree)));
1899             tree->right = tree->left = NULL;
1900             TETYPE(tree) = getSpec(TTYPE(tree) = 
1901                                    tree->opval.val->type);
1902             return tree ;
1903         }
1904         LRVAL(tree) = RRVAL(tree) = 1;
1905         TETYPE(tree) = getSpec (TTYPE(tree) = 
1906                                 computeType(LTYPE(tree),
1907                                             RTYPE(tree)));
1908         return tree;
1909         
1910         /*------------------------------------------------------------------*/
1911         /*----------------------------*/
1912         /*            modulus         */
1913         /*----------------------------*/
1914     case  '%':
1915         if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1916             werror(E_BITWISE_OP);
1917             werror(E_CONTINUE,"left & right types are ");
1918             printTypeChain(LTYPE(tree),stderr);
1919             fprintf(stderr,",");
1920             printTypeChain(RTYPE(tree),stderr);
1921             fprintf(stderr,"\n");
1922             goto errorTreeReturn ;
1923         }
1924         /* if they are both literal then */
1925         /* rewrite the tree */
1926         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1927             tree->type = EX_VALUE ;
1928             tree->opval.val = valMod (valFromType(LETYPE(tree)),
1929                                       valFromType(RETYPE(tree)));                 
1930             tree->right = tree->left = NULL;
1931             TETYPE(tree) = getSpec(TTYPE(tree) = 
1932                                    tree->opval.val->type);
1933             return tree ;
1934         }
1935         LRVAL(tree) = RRVAL(tree) = 1;
1936         TETYPE(tree) = getSpec (TTYPE(tree) = 
1937                                 computeType(LTYPE(tree),
1938                                             RTYPE(tree)));
1939         return tree;
1940         
1941         /*------------------------------------------------------------------*/
1942         /*----------------------------*/
1943         /*  address dereference       */
1944         /*----------------------------*/
1945     case  '*':     /* can be unary  : if right is null then unary operation */
1946         if ( ! tree->right ) {
1947             if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1948                 werror(E_PTR_REQD);
1949                 goto errorTreeReturn ;
1950             }
1951             
1952             if (LRVAL(tree)) {
1953                 werror(E_LVALUE_REQUIRED,"pointer deref");
1954                 goto errorTreeReturn ;  
1955             }
1956             TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ? 
1957                                          LTYPE(tree)->next : NULL );
1958             TETYPE(tree) = getSpec(TTYPE(tree));
1959             tree->args = tree->left->args ;
1960             tree->hasVargs = tree->left->hasVargs ;
1961             SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
1962             return tree ;
1963         }
1964         
1965         /*------------------------------------------------------------------*/
1966         /*----------------------------*/
1967         /*      multiplication        */
1968         /*----------------------------*/
1969         if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1970             werror(E_INVALID_OP,"multiplication");
1971             goto errorTreeReturn ;
1972         }
1973         
1974         /* if they are both literal then */
1975         /* rewrite the tree */
1976         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1977             tree->type = EX_VALUE ;
1978             tree->opval.val = valMult (valFromType(LETYPE(tree)),
1979                                        valFromType(RETYPE(tree)));                 
1980             tree->right = tree->left = NULL;
1981             TETYPE(tree) = getSpec(TTYPE(tree) = 
1982                                    tree->opval.val->type);
1983             return tree ;
1984         }
1985
1986         /* if left is a literal exchange left & right */
1987         if (IS_LITERAL(LTYPE(tree))) {
1988             ast *tTree = tree->left ;
1989             tree->left = tree->right ;
1990             tree->right= tTree ;
1991         }
1992                 
1993         LRVAL(tree) = RRVAL(tree) = 1;
1994         TETYPE(tree) = getSpec (TTYPE(tree) = 
1995                                 computeType(LTYPE(tree),
1996                                             RTYPE(tree)));                        
1997         return tree ;
1998         
1999         /*------------------------------------------------------------------*/
2000         /*----------------------------*/
2001         /*    unary '+' operator      */
2002         /*----------------------------*/
2003     case '+' :  
2004         /* if unary plus */
2005         if ( ! tree->right ) {
2006             if (!IS_INTEGRAL(LTYPE(tree))) {
2007                 werror(E_UNARY_OP,'+');
2008                 goto errorTreeReturn ;
2009             }
2010             
2011             /* if left is a literal then do it */
2012             if (IS_LITERAL(LTYPE(tree))) {
2013                 tree->type = EX_VALUE ;
2014                 tree->opval.val = valFromType(LETYPE(tree));          
2015                 tree->left = NULL ;
2016                 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2017                 return tree ;
2018             }
2019             LRVAL(tree) = 1;
2020             COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)); 
2021             return tree ;
2022         }
2023         
2024         /*------------------------------------------------------------------*/
2025         /*----------------------------*/
2026         /*      addition              */
2027         /*----------------------------*/
2028         
2029         /* this is not a unary operation */
2030         /* if both pointers then problem */
2031         if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2032             (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2033             werror(E_PTR_PLUS_PTR);
2034             goto errorTreeReturn ;
2035         }       
2036
2037         if (!IS_ARITHMETIC(LTYPE(tree)) && 
2038             !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2039             werror(E_PLUS_INVALID,"+");
2040             goto errorTreeReturn ;
2041         }
2042         
2043         if (!IS_ARITHMETIC(RTYPE(tree)) && 
2044             !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2045             werror(E_PLUS_INVALID,"+");
2046             goto errorTreeReturn;
2047         }
2048         /* if they are both literal then */
2049         /* rewrite the tree */
2050         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2051             tree->type = EX_VALUE ;
2052             tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2053                                        valFromType(RETYPE(tree))); 
2054             tree->right = tree->left = NULL;
2055             TETYPE(tree) = getSpec(TTYPE(tree) = 
2056                                    tree->opval.val->type);
2057             return tree ;
2058         }
2059         
2060         /* if the right is a pointer or left is a literal 
2061            xchange left & right */
2062         if (IS_ARRAY(RTYPE(tree)) || 
2063             IS_PTR(RTYPE(tree))   || 
2064             IS_LITERAL(LTYPE(tree))) {
2065             ast *tTree = tree->left ;
2066             tree->left = tree->right ;
2067             tree->right= tTree ;
2068         }
2069
2070         LRVAL(tree) = RRVAL(tree) = 1;  
2071         /* if the left is a pointer */
2072         if (IS_PTR(LTYPE(tree)))      
2073             TETYPE(tree) = getSpec(TTYPE(tree) =
2074                                    LTYPE(tree));
2075         else
2076             TETYPE(tree) = getSpec(TTYPE(tree) = 
2077                                    computeType(LTYPE(tree),
2078                                                RTYPE(tree)));
2079         return tree ;
2080         
2081         /*------------------------------------------------------------------*/
2082         /*----------------------------*/
2083         /*      unary '-'             */
2084         /*----------------------------*/
2085     case '-' :  /* can be unary   */
2086         /* if right is null then unary */
2087         if ( ! tree->right ) {
2088             
2089             if (!IS_ARITHMETIC(LTYPE(tree))) {
2090                 werror(E_UNARY_OP,tree->opval.op);
2091                 goto errorTreeReturn ;
2092             }
2093             
2094             /* if left is a literal then do it */
2095             if (IS_LITERAL(LTYPE(tree))) {
2096                 tree->type = EX_VALUE ;
2097                 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2098                 tree->left = NULL ;
2099                 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2100                 return tree ;
2101             }
2102             LRVAL(tree) = 1;
2103             TTYPE(tree) =  LTYPE(tree); 
2104             return tree ;
2105         }
2106         
2107         /*------------------------------------------------------------------*/
2108         /*----------------------------*/
2109         /*    subtraction             */
2110         /*----------------------------*/
2111         
2112         if (!(IS_PTR(LTYPE(tree)) || 
2113               IS_ARRAY(LTYPE(tree)) || 
2114               IS_ARITHMETIC(LTYPE(tree)))) {
2115             werror(E_PLUS_INVALID,"-");
2116             goto errorTreeReturn ;
2117         }
2118         
2119         if (!(IS_PTR(RTYPE(tree)) || 
2120               IS_ARRAY(RTYPE(tree)) || 
2121               IS_ARITHMETIC(RTYPE(tree)))) {
2122             werror(E_PLUS_INVALID,"-");
2123             goto errorTreeReturn ;
2124         }
2125         
2126         if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2127             ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) || 
2128                IS_INTEGRAL(RTYPE(tree)))   ) {
2129             werror(E_PLUS_INVALID,"-");
2130             goto errorTreeReturn ;
2131         }
2132
2133         /* if they are both literal then */
2134         /* rewrite the tree */
2135         if (IS_LITERAL(RTYPE(tree)) &&  IS_LITERAL(LTYPE(tree))) {
2136             tree->type = EX_VALUE ;
2137             tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2138                                         valFromType(RETYPE(tree)));  
2139             tree->right = tree->left = NULL;
2140             TETYPE(tree) = getSpec(TTYPE(tree) = 
2141                                    tree->opval.val->type);
2142             return tree ;
2143         }
2144         
2145         /* if the left & right are equal then zero */
2146         if (isAstEqual(tree->left,tree->right)) {
2147             tree->type = EX_VALUE;
2148             tree->left = tree->right = NULL;
2149             tree->opval.val = constVal("0");
2150             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2151             return tree;
2152         }
2153
2154         /* if both of them are pointers or arrays then */
2155         /* the result is going to be an integer        */
2156         if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2157             ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree)))) 
2158             TETYPE(tree) = TTYPE(tree) = newIntLink();
2159         else 
2160             /* if only the left is a pointer */
2161             /* then result is a pointer      */
2162             if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) 
2163                 TETYPE(tree) = getSpec(TTYPE(tree) =
2164                                        LTYPE(tree));
2165             else
2166                 TETYPE(tree) = getSpec (TTYPE(tree) = 
2167                                         computeType(LTYPE(tree),
2168                                                     RTYPE(tree))); 
2169         LRVAL(tree) = RRVAL(tree) = 1;
2170         return tree ;  
2171         
2172         /*------------------------------------------------------------------*/
2173         /*----------------------------*/
2174         /*    compliment              */
2175         /*----------------------------*/
2176     case '~' :
2177         /* can be only integral type */
2178         if (!IS_INTEGRAL(LTYPE(tree))) {
2179             werror(E_UNARY_OP,tree->opval.op);
2180             goto errorTreeReturn ;
2181         } 
2182         
2183         /* if left is a literal then do it */
2184         if (IS_LITERAL(LTYPE(tree))) {
2185             tree->type = EX_VALUE ;
2186             tree->opval.val = valComplement(valFromType(LETYPE(tree)));     
2187             tree->left = NULL ;
2188             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2189             return tree ;
2190         }
2191         LRVAL(tree) = 1;
2192         COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2193         return tree ;
2194         
2195         /*------------------------------------------------------------------*/
2196         /*----------------------------*/
2197         /*           not              */
2198         /*----------------------------*/
2199     case '!' :
2200         /* can be pointer */
2201         if (!IS_ARITHMETIC(LTYPE(tree)) && 
2202             !IS_PTR(LTYPE(tree))        && 
2203             !IS_ARRAY(LTYPE(tree))) {
2204             werror(E_UNARY_OP,tree->opval.op);
2205             goto errorTreeReturn ;
2206         }
2207         
2208         /* if left is a literal then do it */
2209         if (IS_LITERAL(LTYPE(tree))) {
2210             tree->type = EX_VALUE ;
2211             tree->opval.val = valNot(valFromType(LETYPE(tree)));           
2212             tree->left = NULL ;
2213             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2214             return tree ;
2215         }
2216         LRVAL(tree) = 1;
2217         TTYPE(tree) = TETYPE(tree) = newCharLink();
2218         return tree ;
2219         
2220         /*------------------------------------------------------------------*/
2221         /*----------------------------*/
2222         /*           shift            */
2223         /*----------------------------*/
2224     case RRC:
2225     case RLC:
2226         TTYPE(tree) = LTYPE(tree);
2227         TETYPE(tree) = LETYPE(tree);
2228         return tree ;
2229         
2230     case GETHBIT:
2231         TTYPE(tree) = TETYPE(tree) = newCharLink();       
2232         return tree;
2233
2234     case LEFT_OP:
2235     case RIGHT_OP:
2236         if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {  
2237             werror(E_SHIFT_OP_INVALID);
2238             werror(E_CONTINUE,"left & right types are ");
2239             printTypeChain(LTYPE(tree),stderr);
2240             fprintf(stderr,",");
2241             printTypeChain(RTYPE(tree),stderr);
2242             fprintf(stderr,"\n");
2243             goto errorTreeReturn ;
2244         }
2245
2246         /* if they are both literal then */
2247         /* rewrite the tree */
2248         if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2249             tree->type = EX_VALUE ;
2250             tree->opval.val = valShift (valFromType(LETYPE(tree)),
2251                                         valFromType(RETYPE(tree)),
2252                                         (tree->opval.op == LEFT_OP ? 1 : 0));             
2253             tree->right = tree->left = NULL;
2254             TETYPE(tree) = getSpec(TTYPE(tree) = 
2255                                    tree->opval.val->type);
2256             return tree ;
2257         }
2258         /* if only the right side is a literal & we are
2259            shifting more than size of the left operand then zero */
2260         if (IS_LITERAL(RTYPE(tree)) && 
2261             ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2262             (getSize(LTYPE(tree))*8)) {
2263             werror(W_SHIFT_CHANGED, 
2264                    (tree->opval.op == LEFT_OP ? "left" : "right"));
2265             tree->type = EX_VALUE;
2266             tree->left = tree->right = NULL;
2267             tree->opval.val = constVal("0");
2268             TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2269             return tree;
2270         }
2271         LRVAL(tree) = RRVAL(tree) = 1;
2272         if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {          
2273             COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));     
2274         } else {
2275             COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2276         }
2277         return tree ;
2278         
2279         /*------------------------------------------------------------------*/
2280         /*----------------------------*/
2281         /*         casting            */
2282         /*----------------------------*/
2283     case CAST:  /* change the type   */
2284         /* cannot cast to an aggregate type */
2285         if (IS_AGGREGATE(LTYPE(tree))) {
2286             werror(E_CAST_ILLEGAL);
2287             goto errorTreeReturn ;
2288         }
2289         
2290         /* if the right is a literal replace the tree */
2291         if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2292             tree->type = EX_VALUE ;
2293             tree->opval.val = 
2294                 valCastLiteral(LTYPE(tree),
2295                                floatFromVal(valFromType(RETYPE(tree))));
2296             tree->left = NULL;
2297             tree->right = NULL;
2298             TTYPE(tree) = tree->opval.val->type;            
2299         }
2300         else {
2301             TTYPE(tree) = LTYPE(tree);
2302             LRVAL(tree) = 1;
2303         }
2304
2305         TETYPE(tree) = getSpec(TTYPE(tree)); 
2306         
2307         return tree;
2308         
2309         /*------------------------------------------------------------------*/
2310         /*----------------------------*/
2311         /*       logical &&, ||       */
2312         /*----------------------------*/
2313     case AND_OP:
2314     case OR_OP:
2315         /* each must me arithmetic type or be a pointer */
2316         if (!IS_PTR(LTYPE(tree)) && 
2317             !IS_ARRAY(LTYPE(tree)) && 
2318             !IS_INTEGRAL(LTYPE(tree))) {
2319             werror(E_COMPARE_OP);
2320             goto errorTreeReturn ;
2321         }
2322         
2323         if (!IS_PTR(RTYPE(tree)) &&     
2324             !IS_ARRAY(RTYPE(tree)) && 
2325             !IS_INTEGRAL(RTYPE(tree))) {
2326             werror(E_COMPARE_OP);
2327             goto errorTreeReturn ;
2328         }
2329         /* if they are both literal then */
2330         /* rewrite the tree */
2331         if (IS_LITERAL(RTYPE(tree)) &&
2332             IS_LITERAL(LTYPE(tree))) {
2333             tree->type = EX_VALUE ;
2334             tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2335                                              valFromType(RETYPE(tree)),
2336                                              tree->opval.op);               
2337             tree->right = tree->left = NULL;
2338             TETYPE(tree) = getSpec(TTYPE(tree) = 
2339                                    tree->opval.val->type);
2340             return tree ;
2341         }
2342         LRVAL(tree) = RRVAL(tree) = 1;
2343         TTYPE(tree) = TETYPE(tree) = newCharLink();
2344         return tree ;
2345         
2346         /*------------------------------------------------------------------*/
2347         /*----------------------------*/
2348         /*     comparison operators   */
2349         /*----------------------------*/    
2350     case '>' :
2351     case '<' :
2352     case LE_OP :
2353     case GE_OP :
2354     case EQ_OP :
2355     case NE_OP :
2356         {
2357             ast *lt = optimizeCompare(tree);
2358             
2359             if ( tree != lt )
2360                 return lt;
2361         }
2362
2363         /* if they are pointers they must be castable */
2364         if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2365             if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2366                 werror(E_COMPARE_OP);
2367                 fprintf(stderr,"comparing type ");
2368                 printTypeChain(LTYPE(tree),stderr);
2369                 fprintf(stderr,"to type ");
2370                 printTypeChain(RTYPE(tree),stderr);
2371                 fprintf(stderr,"\n");
2372                 goto errorTreeReturn ;
2373             }
2374         } 
2375         /* else they should be promotable to one another */
2376         else {
2377             if (!(  ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2378                     ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))))) 
2379                 
2380                 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2381                     werror(E_COMPARE_OP);
2382                     fprintf(stderr,"comparing type ");
2383                     printTypeChain(LTYPE(tree),stderr);
2384                     fprintf(stderr,"to type ");
2385                     printTypeChain(RTYPE(tree),stderr);
2386                     fprintf(stderr,"\n");
2387                     goto errorTreeReturn ;
2388                 }
2389         }
2390         
2391         /* if they are both literal then */
2392         /* rewrite the tree */
2393         if (IS_LITERAL(RTYPE(tree)) &&
2394             IS_LITERAL(LTYPE(tree))) {
2395             tree->type = EX_VALUE ;
2396             tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2397                                           valFromType(RETYPE(tree)),
2398                                           tree->opval.op);                 
2399             tree->right = tree->left = NULL;
2400             TETYPE(tree) = getSpec(TTYPE(tree) = 
2401                                    tree->opval.val->type);
2402             return tree ;
2403         }
2404         LRVAL(tree) = RRVAL(tree) = 1;
2405         TTYPE(tree) = TETYPE(tree) = newCharLink();
2406         return tree ;
2407         
2408         /*------------------------------------------------------------------*/
2409         /*----------------------------*/
2410         /*             sizeof         */
2411         /*----------------------------*/    
2412     case SIZEOF :  /* evaluate wihout code generation */
2413         /* change the type to a integer */
2414         tree->type = EX_VALUE;
2415         sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2416         tree->opval.val = constVal(buffer);
2417         tree->right = tree->left = NULL;
2418         TETYPE(tree) = getSpec(TTYPE(tree) = 
2419                                tree->opval.val->type);
2420         return tree;     
2421         
2422         /*------------------------------------------------------------------*/
2423         /*----------------------------*/
2424         /* conditional operator  '?'  */
2425         /*----------------------------*/    
2426     case '?' :
2427         /* the type is one on the left */
2428         TTYPE(tree) = LTYPE(tree);
2429         TETYPE(tree)= getSpec (TTYPE(tree));
2430         return tree ;
2431         
2432     case ':' :
2433         /* if they don't match we have a problem */
2434         if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2435             werror(E_TYPE_MISMATCH,"conditional operator"," ");
2436             goto errorTreeReturn ;
2437         }
2438         
2439         TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2440         TETYPE(tree)= getSpec(TTYPE(tree));
2441         return tree ;
2442         
2443         
2444         /*------------------------------------------------------------------*/
2445         /*----------------------------*/
2446         /*    assignment operators    */
2447         /*----------------------------*/    
2448     case MUL_ASSIGN:
2449     case DIV_ASSIGN:
2450         /* for these it must be both must be integral */
2451         if (!IS_ARITHMETIC(LTYPE(tree)) ||
2452             !IS_ARITHMETIC(RTYPE(tree))) {
2453             werror (E_OPS_INTEGRAL);
2454             goto errorTreeReturn ;
2455         }
2456         RRVAL(tree) = 1;
2457         TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2458
2459         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2460             werror(E_CODE_WRITE," ");
2461
2462         if (LRVAL(tree)) {
2463             werror(E_LVALUE_REQUIRED,"*= or /=");
2464             goto errorTreeReturn ;      
2465         }
2466         LLVAL(tree) = 1;
2467         return tree ;
2468
2469     case AND_ASSIGN:
2470     case OR_ASSIGN:
2471     case XOR_ASSIGN:
2472     case RIGHT_ASSIGN:
2473     case LEFT_ASSIGN:
2474         /* for these it must be both must be integral */
2475         if (!IS_INTEGRAL(LTYPE(tree)) ||
2476             !IS_INTEGRAL(RTYPE(tree))) {
2477             werror (E_OPS_INTEGRAL);
2478             goto errorTreeReturn ;
2479         }
2480         RRVAL(tree) = 1;
2481         TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2482
2483         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2484             werror(E_CODE_WRITE," ");
2485
2486         if (LRVAL(tree)) {
2487             werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2488             goto errorTreeReturn ;      
2489         }
2490         LLVAL(tree) = 1;
2491         return tree ;
2492         
2493         /*------------------------------------------------------------------*/
2494         /*----------------------------*/
2495         /*    -= operator             */
2496         /*----------------------------*/    
2497     case SUB_ASSIGN:
2498         if (!(IS_PTR(LTYPE(tree))   ||
2499               IS_ARITHMETIC(LTYPE(tree)))) {
2500             werror(E_PLUS_INVALID,"-=");
2501             goto errorTreeReturn ;
2502         }
2503         
2504         if (!(IS_PTR(RTYPE(tree))   ||
2505               IS_ARITHMETIC(RTYPE(tree)))) {
2506             werror(E_PLUS_INVALID,"-=");
2507             goto errorTreeReturn ;
2508         }
2509         RRVAL(tree) = 1;
2510         TETYPE(tree) = getSpec (TTYPE(tree) = 
2511                                 computeType(LTYPE(tree),
2512                                             RTYPE(tree)));  
2513
2514         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2515             werror(E_CODE_WRITE," ");
2516
2517         if (LRVAL(tree)) {
2518             werror(E_LVALUE_REQUIRED,"-=");
2519             goto errorTreeReturn ;      
2520         }
2521         LLVAL(tree) = 1;
2522         return tree;
2523         
2524         /*------------------------------------------------------------------*/
2525         /*----------------------------*/
2526         /*          += operator       */
2527         /*----------------------------*/    
2528     case ADD_ASSIGN:
2529         /* this is not a unary operation */
2530         /* if both pointers then problem */
2531         if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2532             werror(E_PTR_PLUS_PTR);
2533             goto errorTreeReturn ;
2534         }
2535         
2536         if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree)))  {
2537             werror(E_PLUS_INVALID,"+=");
2538             goto errorTreeReturn ;
2539         }
2540         
2541         if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree)))  {
2542             werror(E_PLUS_INVALID,"+=");
2543             goto errorTreeReturn;
2544         }
2545         RRVAL(tree) = 1;
2546         TETYPE(tree) = getSpec (TTYPE(tree) = 
2547                                 computeType(LTYPE(tree),
2548                                             RTYPE(tree)));  
2549
2550         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2551             werror(E_CODE_WRITE," ");
2552
2553         if (LRVAL(tree)) {
2554             werror(E_LVALUE_REQUIRED,"+=");
2555             goto errorTreeReturn ;      
2556         }
2557
2558         tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2559         tree->opval.op = '=';       
2560         return tree;
2561         
2562         /*------------------------------------------------------------------*/
2563         /*----------------------------*/
2564         /*      straight assignemnt   */
2565         /*----------------------------*/    
2566     case '=' :
2567         /* cannot be an aggregate */
2568         if (IS_AGGREGATE(LTYPE(tree))) {
2569             werror(E_AGGR_ASSIGN);
2570             goto errorTreeReturn;
2571         }
2572             
2573         /* they should either match or be castable */
2574         if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2575             werror(E_TYPE_MISMATCH,"assignment"," ");
2576             fprintf(stderr,"type --> '"); 
2577             printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2578             fprintf(stderr,"assigned to type --> '"); 
2579             printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2580             goto errorTreeReturn ;
2581         }
2582
2583         /* if the left side of the tree is of type void
2584            then report error */
2585         if (IS_VOID(LTYPE(tree))) {
2586             werror(E_CAST_ZERO);
2587             fprintf(stderr,"type --> '"); 
2588             printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2589             fprintf(stderr,"assigned to type --> '"); 
2590             printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2591         }
2592
2593         /* extra checks for pointer types */
2594         if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2595             !IS_GENPTR(LTYPE(tree))) {
2596           if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2597             werror(W_PTR_ASSIGN);
2598         }
2599
2600         TETYPE(tree) = getSpec(TTYPE(tree) = 
2601                                LTYPE(tree));
2602         RRVAL(tree) = 1;
2603         LLVAL(tree) = 1;
2604         if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2605             werror(E_CODE_WRITE," ");
2606
2607         if (LRVAL(tree)) {
2608             werror(E_LVALUE_REQUIRED,"=");
2609             goto errorTreeReturn ;      
2610         }
2611
2612         return tree ;
2613         
2614         /*------------------------------------------------------------------*/
2615         /*----------------------------*/
2616         /*      comma operator        */
2617         /*----------------------------*/        
2618     case ',' :
2619         TETYPE(tree) = getSpec(TTYPE(tree) =  RTYPE(tree));
2620         return tree ;    
2621         
2622         /*------------------------------------------------------------------*/
2623         /*----------------------------*/
2624         /*       function call        */
2625         /*----------------------------*/        
2626     case CALL   :
2627         parmNumber = 1;
2628
2629
2630         if (processParms (tree->left,
2631                           tree->left->args,
2632                           tree->right,&parmNumber)) 
2633             goto errorTreeReturn ;    
2634
2635         if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2636                 tree->left->args = reverseVal(tree->left->args); 
2637                 reverseParms(tree->right);
2638         }
2639
2640         tree->args = tree->left->args ;
2641         TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2642         return tree;
2643
2644         /*------------------------------------------------------------------*/
2645         /*----------------------------*/
2646         /*     return statement       */
2647         /*----------------------------*/        
2648     case RETURN :
2649         if (!tree->right)
2650             goto voidcheck ;
2651
2652         if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2653             werror(E_RETURN_MISMATCH);
2654             goto errorTreeReturn ;
2655         }
2656
2657         if (IS_VOID(currFunc->type->next) 
2658             && tree->right && 
2659             !IS_VOID(RTYPE(tree))) {
2660             werror(E_FUNC_VOID);
2661             goto errorTreeReturn ;
2662         }
2663         
2664         /* if there is going to be a casing required then add it */
2665         if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
2666             tree->right = 
2667                 decorateType(newNode(CAST,
2668                                      newAst_LINK(copyLinkChain(currFunc->type->next)),
2669                                      tree->right));
2670         }
2671         
2672         RRVAL(tree) = 1;
2673         return tree;
2674
2675         voidcheck :
2676
2677         if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2678             werror(E_VOID_FUNC,currFunc->name);
2679             goto errorTreeReturn ;
2680         }               
2681
2682         TTYPE(tree) = TETYPE(tree) = NULL ;
2683         return tree ;    
2684
2685         /*------------------------------------------------------------------*/
2686         /*----------------------------*/
2687         /*     switch statement       */
2688         /*----------------------------*/        
2689     case SWITCH:
2690         /* the switch value must be an integer */
2691         if (!IS_INTEGRAL(LTYPE(tree))) {
2692             werror (E_SWITCH_NON_INTEGER);
2693             goto errorTreeReturn ;
2694         }
2695         LRVAL(tree) = 1;
2696         TTYPE(tree) = TETYPE(tree) = NULL ;
2697         return tree ;
2698
2699         /*------------------------------------------------------------------*/
2700         /*----------------------------*/
2701         /* ifx Statement              */
2702         /*----------------------------*/
2703     case IFX:
2704         tree->left = backPatchLabels(tree->left,
2705                                      tree->trueLabel,
2706                                      tree->falseLabel);
2707         TTYPE(tree) = TETYPE(tree) = NULL;
2708         return tree;
2709
2710         /*------------------------------------------------------------------*/
2711         /*----------------------------*/
2712         /* for Statement              */
2713         /*----------------------------*/
2714     case FOR:              
2715
2716         decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2717         decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2718         decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2719         
2720         /* if the for loop is reversible then 
2721            reverse it otherwise do what we normally
2722            do */
2723         {
2724             symbol *sym ;
2725             ast *init, *end;
2726
2727             if (isLoopReversible (tree,&sym,&init,&end))
2728                 return reverseLoop (tree,sym,init,end);
2729             else
2730                 return decorateType(createFor ( AST_FOR(tree,trueLabel), 
2731                                                 AST_FOR(tree,continueLabel) ,
2732                                                 AST_FOR(tree,falseLabel) ,
2733                                                 AST_FOR(tree,condLabel)  ,
2734                                                 AST_FOR(tree,initExpr)   , 
2735                                                 AST_FOR(tree,condExpr)   , 
2736                                                 AST_FOR(tree,loopExpr),
2737                                                 tree->left ) );
2738         }
2739     default :
2740         TTYPE(tree) = TETYPE(tree) = NULL ;
2741         return tree ;    
2742     }
2743     
2744     /* some error found this tree will be killed */
2745     errorTreeReturn :     
2746         TTYPE(tree) = TETYPE(tree) = newCharLink();
2747     tree->opval.op = NULLOP ;
2748     tree->isError = 1;
2749     
2750     return tree ;
2751 }
2752
2753 /*-----------------------------------------------------------------*/
2754 /* sizeofOp - processes size of operation                          */
2755 /*-----------------------------------------------------------------*/
2756 value  *sizeofOp( link  *type)
2757 {
2758         char buff[10];
2759
2760         /* get the size and convert it to character  */
2761         sprintf (buff,"%d", getSize(type));
2762
2763         /* now convert into value  */
2764         return  constVal (buff);      
2765 }
2766
2767
2768 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2769 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
2770 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2771 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2772 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2773 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
2774 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
2775
2776 /*-----------------------------------------------------------------*/
2777 /* backPatchLabels - change and or not operators to flow control    */
2778 /*-----------------------------------------------------------------*/
2779 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2780 {  
2781     
2782     if ( ! tree )
2783         return NULL ;
2784     
2785     if ( ! (IS_ANDORNOT(tree)))
2786         return tree ;
2787     
2788     /* if this an and */
2789     if (IS_AND(tree)) {
2790         static int localLbl = 0 ;
2791         symbol *localLabel ;
2792         
2793         sprintf (buffer,"_and_%d",localLbl++);
2794         localLabel = newSymbol(buffer,NestLevel);
2795         
2796         tree->left = backPatchLabels (tree->left, localLabel,falseLabel);    
2797         
2798         /* if left is already a IFX then just change the if true label in that */
2799         if (!IS_IFX(tree->left)) 
2800             tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2801         
2802         tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);    
2803         /* right is a IFX then just join */
2804         if (IS_IFX(tree->right))
2805             return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2806         
2807         tree->right = createLabel(localLabel,tree->right);
2808         tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2809         
2810         return newNode(NULLOP,tree->left,tree->right);
2811     }
2812     
2813     /* if this is an or operation */
2814     if (IS_OR(tree)) {
2815         static int localLbl = 0 ;
2816         symbol *localLabel ;
2817         
2818         sprintf (buffer,"_or_%d",localLbl++);
2819         localLabel = newSymbol(buffer,NestLevel);
2820         
2821         tree->left = backPatchLabels (tree->left, trueLabel,localLabel);    
2822         
2823         /* if left is already a IFX then just change the if true label in that */
2824         if (!IS_IFX(tree->left))                
2825             tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2826         
2827         tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);    
2828         /* right is a IFX then just join */
2829         if (IS_IFX(tree->right))
2830             return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2831         
2832         tree->right = createLabel(localLabel,tree->right);
2833         tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2834         
2835         return newNode(NULLOP,tree->left,tree->right);
2836     }
2837     
2838     /* change not */
2839     if (IS_NOT(tree)) {
2840         int wasnot = IS_NOT(tree->left);
2841         tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2842         
2843         /* if the left is already a IFX */
2844         if ( ! IS_IFX(tree->left) ) 
2845             tree->left = newNode (IFX,tree->left,NULL);
2846         
2847         if (wasnot) {
2848             tree->left->trueLabel = trueLabel ;
2849             tree->left->falseLabel= falseLabel ;
2850         } else {
2851             tree->left->trueLabel = falseLabel ;
2852             tree->left->falseLabel= trueLabel ;
2853         }
2854         return tree->left ;
2855     }
2856     
2857     if (IS_IFX(tree)) {
2858         tree->trueLabel = trueLabel ;
2859         tree->falseLabel= falseLabel;
2860     }
2861     
2862     return tree ;    
2863 }
2864
2865
2866 /*-----------------------------------------------------------------*/
2867 /* createBlock - create expression tree for block                  */
2868 /*-----------------------------------------------------------------*/
2869 ast  *createBlock   ( symbol *decl,   ast  *body )
2870 {
2871     ast *ex ;
2872     
2873     /* if the block has nothing */
2874     if (!body)
2875         return NULL;
2876
2877     ex = newNode(BLOCK,NULL,body);
2878     ex->values.sym = decl ;
2879     
2880     ex->right = ex->right ;
2881     ex->level++ ;
2882     ex->lineno = 0 ;
2883     return ex;
2884 }
2885
2886 /*-----------------------------------------------------------------*/
2887 /* createLabel - creates the expression tree for labels            */
2888 /*-----------------------------------------------------------------*/
2889 ast  *createLabel  ( symbol  *label,  ast  *stmnt  )
2890 {
2891     symbol *csym;
2892     char        name[SDCC_NAME_MAX+1];
2893     ast   *rValue ;
2894     
2895     /* must create fresh symbol if the symbol name  */
2896     /* exists in the symbol table, since there can  */
2897     /* be a variable with the same name as the labl */
2898     if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2899         (csym->level == label->level))
2900         label = newSymbol(label->name,label->level);
2901     
2902     /* change the name before putting it in add _*/
2903     sprintf (name,"%s",label->name);
2904     
2905     /* put the label in the LabelSymbol table    */
2906     /* but first check if a label of the same    */
2907     /* name exists                               */
2908     if ( (csym = findSym(LabelTab,NULL,name)))
2909         werror(E_DUPLICATE_LABEL,label->name);
2910     else
2911         addSym (LabelTab, label, name,label->level,0);
2912     
2913     label->islbl = 1;
2914     label->key = labelKey++ ;
2915     rValue =  newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);  
2916     rValue->lineno = 0;
2917     
2918     return rValue ;
2919 }
2920
2921 /*-----------------------------------------------------------------*/
2922 /* createCase - generates the parsetree for a case statement       */
2923 /*-----------------------------------------------------------------*/
2924 ast  *createCase (ast *swStat, ast *caseVal, ast *stmnt   )
2925 {
2926     char caseLbl[SDCC_NAME_MAX+1];
2927     ast *rexpr;
2928     value *val;
2929     
2930     /* if the switch statement does not exist */
2931     /* then case is out of context            */
2932     if (!swStat) {
2933         werror(E_CASE_CONTEXT);
2934         return NULL ;
2935     }
2936     
2937     caseVal = decorateType(resolveSymbols(caseVal));
2938     /* if not a constant then error  */
2939     if (!IS_LITERAL(caseVal->ftype)) {
2940         werror(E_CASE_CONSTANT);
2941         return NULL ;
2942     }
2943     
2944     /* if not a integer than error */
2945     if (!IS_INTEGRAL(caseVal->ftype)) {
2946         werror(E_CASE_NON_INTEGER);
2947         return NULL;
2948     }
2949
2950     /* find the end of the switch values chain   */
2951     if (!(val = swStat->values.switchVals.swVals))
2952         swStat->values.switchVals.swVals = caseVal->opval.val ;
2953     else {
2954         /* also order the cases according to value */
2955         value *pval = NULL;
2956         int cVal = (int) floatFromVal(caseVal->opval.val);
2957         while (val && (int) floatFromVal(val) < cVal) {
2958             pval = val;
2959             val = val->next ;
2960         }
2961        
2962         /* if we reached the end then */
2963         if (!val) {
2964             pval->next =  caseVal->opval.val;
2965         } else {
2966             /* we found a value greater than */
2967             /* the current value we must add this */
2968             /* before the value */
2969             caseVal->opval.val->next = val;
2970
2971             /* if this was the first in chain */
2972             if (swStat->values.switchVals.swVals == val)
2973                 swStat->values.switchVals.swVals = 
2974                     caseVal->opval.val;
2975             else
2976                 pval->next =  caseVal->opval.val;
2977         }
2978             
2979     }
2980     
2981     /* create the case label   */
2982     sprintf(caseLbl,"_case_%d_%d",
2983             swStat->values.switchVals.swNum,
2984             (int) floatFromVal(caseVal->opval.val));
2985     
2986     rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
2987     rexpr->lineno = 0;
2988     return rexpr;
2989 }
2990
2991 /*-----------------------------------------------------------------*/
2992 /* createDefault - creates the parse tree for the default statement*/
2993 /*-----------------------------------------------------------------*/
2994 ast  *createDefault (ast *swStat, ast *stmnt)
2995 {
2996     char  defLbl[SDCC_NAME_MAX+1];
2997     
2998     /* if the switch statement does not exist */
2999     /* then case is out of context            */
3000     if (!swStat) {
3001         werror(E_CASE_CONTEXT);
3002         return NULL ;
3003     }
3004     
3005     /* turn on the default flag   */
3006     swStat->values.switchVals.swDefault = 1   ;
3007     
3008     /* create the label  */
3009     sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3010     return createLabel(newSymbol(defLbl,0),stmnt);   
3011 }
3012
3013 /*-----------------------------------------------------------------*/
3014 /* createIf - creates the parsetree for the if statement           */
3015 /*-----------------------------------------------------------------*/
3016 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3017 {
3018     static int Lblnum = 0 ;
3019     ast *ifTree ;
3020     symbol *ifTrue , *ifFalse, *ifEnd ;
3021     
3022     /* if neither exists */
3023     if (! elseBody && !ifBody)
3024         return condAst ;
3025     
3026     /* create the labels */
3027     sprintf (buffer,"_iffalse_%d",Lblnum);
3028     ifFalse = newSymbol (buffer,NestLevel);
3029     /* if no else body then end == false */
3030     if ( ! elseBody ) 
3031         ifEnd = ifFalse ;
3032     else {
3033         sprintf (buffer,"_ifend_%d",Lblnum);
3034         ifEnd = newSymbol (buffer,NestLevel);
3035     }
3036
3037     sprintf (buffer,"_iftrue_%d",Lblnum);
3038     ifTrue = newSymbol (buffer,NestLevel);
3039         
3040     Lblnum++ ;
3041
3042     /* attach the ifTrue label to the top of it body */
3043     ifBody = createLabel(ifTrue,ifBody);
3044     /* attach a goto end to the ifBody if else is present */
3045     if ( elseBody ) {
3046         ifBody = newNode(NULLOP,ifBody,
3047                          newNode(GOTO,
3048                                  newAst_VALUE(symbolVal(ifEnd)),
3049                                  NULL));
3050         /* put the elseLabel on the else body */
3051         elseBody = createLabel (ifFalse,elseBody);
3052         /* out the end at the end of the body */
3053         elseBody = newNode(NULLOP,
3054                            elseBody,
3055                            createLabel(ifEnd,NULL));
3056     }
3057     else {
3058         ifBody = newNode(NULLOP,ifBody,
3059                          createLabel(ifFalse,NULL));
3060     }
3061     condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3062     if (IS_IFX(condAst))
3063         ifTree = condAst;
3064     else 
3065         ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3066     
3067     return newNode(NULLOP,ifTree,
3068                    newNode(NULLOP,ifBody,elseBody));
3069     
3070 }
3071
3072 /*-----------------------------------------------------------------*/
3073 /* createDo - creates parse tree for do                            */
3074 /*        _dobody_n:                                               */
3075 /*            statements                                           */
3076 /*        _docontinue_n:                                           */
3077 /*            condition_expression +-> trueLabel -> _dobody_n      */
3078 /*                                 |                               */
3079 /*                                 +-> falseLabel-> _dobreak_n     */
3080 /*        _dobreak_n:                                              */
3081 /*-----------------------------------------------------------------*/
3082 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3083                 symbol *falseLabel, ast *condAst, ast *doBody )
3084 {
3085     ast *doTree ;
3086     
3087     
3088     /* if the body does not exist then it is simple */
3089     if ( ! doBody ) {
3090         condAst = backPatchLabels(condAst,continueLabel,NULL);
3091         doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst) 
3092                   : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3093         doTree->trueLabel = continueLabel ;
3094         doTree->falseLabel= NULL ;
3095         return doTree ;
3096     }
3097     
3098     /* otherwise we have a body */
3099     condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3100     
3101     /* attach the body label to the top */
3102     doBody = createLabel(trueLabel,doBody);
3103     /* attach the continue label to end of body */
3104     doBody = newNode(NULLOP, doBody, 
3105                      createLabel(continueLabel,NULL));
3106     
3107     /* now put the break label at the end */
3108     if (IS_IFX(condAst))
3109         doTree = condAst;
3110     else 
3111         doTree = newIfxNode(condAst,trueLabel,falseLabel);
3112     
3113     doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3114     
3115     /* putting it together */
3116     return newNode(NULLOP,doBody,doTree);
3117 }
3118
3119 /*-----------------------------------------------------------------*/
3120 /* createFor - creates parse tree for 'for' statement              */
3121 /*        initExpr                                                 */
3122 /*   _forcond_n:                                                   */
3123 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3124 /*                  |                                              */
3125 /*                  +-> falseLabel-> _forbreak_n                   */
3126 /*   _forbody_n:                                                   */
3127 /*        statements                                               */
3128 /*   _forcontinue_n:                                               */
3129 /*        loopExpr                                                 */
3130 /*        goto _forcond_n ;                                        */
3131 /*   _forbreak_n:                                                  */
3132 /*-----------------------------------------------------------------*/
3133 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3134                  symbol *falseLabel,symbol *condLabel     ,
3135                  ast *initExpr, ast *condExpr, ast *loopExpr,
3136                  ast *forBody )
3137 {
3138     ast *forTree ;      
3139
3140     /* if loopexpression not present then we can generate it */
3141     /* the same way as a while */
3142     if ( ! loopExpr ) 
3143         return newNode(NULLOP,initExpr,
3144                        createWhile (trueLabel, continueLabel, 
3145                                     falseLabel,condExpr, forBody ));
3146     /* vanilla for statement */
3147     condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3148     
3149     if (condExpr && !IS_IFX(condExpr)) 
3150         condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3151     
3152     
3153     /* attach condition label to condition */
3154     condExpr = createLabel(condLabel,condExpr);
3155     
3156     /* attach body label to body */
3157     forBody = createLabel(trueLabel,forBody);
3158     
3159     /* attach continue to forLoop expression & attach */
3160     /* goto the forcond @ and of loopExpression       */
3161     loopExpr = createLabel(continueLabel,
3162                            newNode(NULLOP,
3163                                    loopExpr,
3164                                    newNode(GOTO,
3165                                            newAst_VALUE(symbolVal(condLabel)),
3166                                            NULL)));
3167     /* now start putting them together */
3168     forTree = newNode(NULLOP,initExpr,condExpr);
3169     forTree = newNode(NULLOP,forTree,forBody);
3170     forTree = newNode(NULLOP,forTree,loopExpr);
3171     /* finally add the break label */
3172     forTree = newNode(NULLOP,forTree,
3173                       createLabel(falseLabel,NULL));
3174     return forTree ;
3175 }
3176
3177 /*-----------------------------------------------------------------*/
3178 /* createWhile - creates parse tree for while statement            */
3179 /*               the while statement will be created as follows    */
3180 /*                                                                 */
3181 /*      _while_continue_n:                                         */
3182 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3183 /*                                 |                               */
3184 /*                                 +-> falseLabel -> _while_break_n*/
3185 /*      _while_body_n:                                             */
3186 /*            statements                                           */
3187 /*            goto _while_continue_n                               */
3188 /*      _while_break_n:                                            */
3189 /*-----------------------------------------------------------------*/
3190 ast *createWhile (symbol *trueLabel, symbol *continueLabel, 
3191                    symbol *falseLabel,ast *condExpr, ast *whileBody )
3192 {
3193     ast *whileTree ;
3194         
3195     /* put the continue label */
3196     condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3197     condExpr = createLabel(continueLabel,condExpr);
3198     condExpr->lineno = 0;
3199     
3200     /* put the body label in front of the body */
3201     whileBody = createLabel(trueLabel,whileBody);
3202     whileBody->lineno = 0;
3203     /* put a jump to continue at the end of the body */
3204     /* and put break label at the end of the body */
3205     whileBody = newNode(NULLOP,
3206                         whileBody,
3207                         newNode(GOTO,
3208                                 newAst_VALUE(symbolVal(continueLabel)),
3209                                 createLabel(falseLabel,NULL)));
3210     
3211     /* put it all together */
3212     if ( IS_IFX(condExpr) )
3213         whileTree = condExpr ;
3214     else {
3215         whileTree = newNode (IFX, condExpr,NULL );      
3216         /* put the true & false labels in place */
3217         whileTree->trueLabel = trueLabel ;
3218         whileTree->falseLabel= falseLabel;
3219     }
3220     
3221     return newNode(NULLOP,whileTree,whileBody );
3222 }
3223
3224 /*-----------------------------------------------------------------*/
3225 /* optimizeGetHbit - get highest order bit of the expression       */
3226 /*-----------------------------------------------------------------*/
3227 ast *optimizeGetHbit (ast *tree)
3228 {
3229     int i,j;
3230     /* if this is not a bit and */
3231     if (!IS_BITAND(tree))
3232         return tree;
3233     
3234     /* will look for tree of the form
3235        ( expr >> ((sizeof expr) -1) ) & 1 */
3236     if (!IS_AST_LIT_VALUE(tree->right))
3237         return tree;
3238
3239     if (AST_LIT_VALUE(tree->right) != 1)
3240         return tree;
3241
3242     if (!IS_RIGHT_OP(tree->left))
3243         return tree;
3244
3245     if (!IS_AST_LIT_VALUE(tree->left->right))
3246         return tree;
3247
3248     if ((i = AST_LIT_VALUE(tree->left->right)) !=
3249         ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3250         return tree;
3251
3252     return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3253         
3254 }
3255
3256 /*-----------------------------------------------------------------*/
3257 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3258 /*-----------------------------------------------------------------*/
3259 ast *optimizeRRCRLC ( ast *root )
3260 {
3261     /* will look for trees of the form
3262        (?expr << 1) | (?expr >> 7) or
3263        (?expr >> 7) | (?expr << 1) will make that
3264        into a RLC : operation ..
3265        Will also look for 
3266        (?expr >> 1) | (?expr << 7) or
3267        (?expr << 7) | (?expr >> 1) will make that
3268        into a RRC operation 
3269        note : by 7 I mean (number of bits required to hold the
3270        variable -1 ) */
3271     /* if the root operations is not a | operation the not */
3272     if (!IS_BITOR(root))
3273         return root ;
3274
3275     /* I have to think of a better way to match patterns this sucks */
3276     /* that aside let start looking for the first case : I use a the
3277        negative check a lot to improve the efficiency */
3278     /* (?expr << 1) | (?expr >> 7) */
3279     if (IS_LEFT_OP(root->left)    && 
3280         IS_RIGHT_OP(root->right)  ) {   
3281         
3282         if (!SPEC_USIGN(TETYPE(root->left->left)))
3283             return root;
3284
3285         if (!IS_AST_LIT_VALUE(root->left->right) ||
3286             !IS_AST_LIT_VALUE(root->right->right))
3287             goto tryNext0;
3288
3289         /* make sure it is the same expression */
3290         if (!isAstEqual(root->left->left,
3291                         root->right->left))
3292             goto tryNext0;
3293         
3294         if (AST_LIT_VALUE(root->left->right) != 1 )
3295             goto tryNext0 ;
3296         
3297         if (AST_LIT_VALUE(root->right->right) !=
3298             (getSize(TTYPE(root->left->left))*8 - 1))
3299             goto tryNext0 ;
3300
3301         /* whew got the first case : create the AST */
3302         return  newNode(RLC,root->left->left,NULL);     
3303     }
3304
3305  tryNext0:
3306     /* check for second case */
3307     /* (?expr >> 7) | (?expr << 1) */
3308     if (IS_LEFT_OP(root->right)    && 
3309         IS_RIGHT_OP(root->left)  ) {     
3310
3311         if (!SPEC_USIGN(TETYPE(root->left->left)))
3312             return root;
3313         
3314         if (!IS_AST_LIT_VALUE(root->left->right) ||
3315             !IS_AST_LIT_VALUE(root->right->right))
3316             goto tryNext1 ;
3317         
3318         /* make sure it is the same symbol */
3319         if (!isAstEqual(root->left->left,
3320                         root->right->left))
3321             goto tryNext1 ;
3322         
3323         if (AST_LIT_VALUE(root->right->right) != 1 )
3324             goto tryNext1 ;
3325         
3326         if (AST_LIT_VALUE(root->left->right) !=
3327             (getSize(TTYPE(root->left->left))*8 - 1))
3328             goto tryNext1 ;
3329
3330         /* whew got the first case : create the AST */
3331         return  newNode(RLC,root->left->left,NULL);
3332         
3333     }
3334
3335  tryNext1:
3336     /* third case for RRC */
3337     /*  (?symbol >> 1) | (?symbol << 7) */
3338     if (IS_LEFT_OP(root->right)    && 
3339         IS_RIGHT_OP(root->left)  ) {    
3340
3341         if (!SPEC_USIGN(TETYPE(root->left->left)))
3342             return root;
3343         
3344         if (!IS_AST_LIT_VALUE(root->left->right) ||
3345             !IS_AST_LIT_VALUE(root->right->right))
3346             goto tryNext2;
3347         
3348         /* make sure it is the same symbol */
3349         if (!isAstEqual(root->left->left,
3350                         root->right->left))
3351             goto tryNext2;
3352         
3353         if (AST_LIT_VALUE(root->left->right) != 1 )
3354             goto tryNext2;
3355         
3356         if (AST_LIT_VALUE(root->right->right) !=
3357             (getSize(TTYPE(root->left->left))*8 - 1))
3358             goto tryNext2;
3359
3360         /* whew got the first case : create the AST */
3361         return newNode(RRC,root->left->left,NULL);
3362         
3363     }
3364  tryNext2:
3365     /* fourth and last case for now */
3366     /* (?symbol << 7) | (?symbol >> 1) */
3367     if (IS_RIGHT_OP(root->right)    && 
3368         IS_LEFT_OP(root->left)  ) {     
3369
3370         if (!SPEC_USIGN(TETYPE(root->left->left)))
3371             return root;
3372         
3373         if (!IS_AST_LIT_VALUE(root->left->right) ||
3374             !IS_AST_LIT_VALUE(root->right->right))
3375             return root;
3376
3377         /* make sure it is the same symbol */
3378         if (!isAstEqual(root->left->left,
3379                         root->right->left))
3380             return root;
3381         
3382         if (AST_LIT_VALUE(root->right->right) != 1 )
3383             return root ;
3384         
3385         if (AST_LIT_VALUE(root->left->right) !=
3386             (getSize(TTYPE(root->left->left))*8 - 1))
3387             return root ;
3388
3389         /* whew got the first case : create the AST */
3390         return  newNode(RRC,root->left->left,NULL);
3391         
3392     }
3393
3394     /* not found return root */
3395     return root;
3396 }
3397
3398 /*-----------------------------------------------------------------*/
3399 /* optimizeCompare - otimizes compares for bit variables           */
3400 /*-----------------------------------------------------------------*/
3401 ast  *optimizeCompare ( ast *root )
3402 {
3403     ast *optExpr = NULL;
3404     value       *vleft;
3405     value       *vright;
3406     unsigned int litValue ;
3407     
3408     /* if nothing then return nothing */
3409     if (!root)
3410         return NULL ;
3411     
3412     /* if not a compare op then do leaves */
3413     if (!IS_COMPARE_OP(root)) {
3414         root->left = optimizeCompare (root->left);
3415         root->right= optimizeCompare (root->right);
3416         return root ;
3417     }
3418     
3419     /* if left & right are the same then depending 
3420        of the operation do */
3421     if (isAstEqual(root->left,root->right)) {
3422         switch (root->opval.op) {
3423         case '>' :
3424         case '<' :
3425         case NE_OP :
3426             optExpr = newAst_VALUE(constVal("0"));
3427             break;
3428         case GE_OP :
3429         case LE_OP :
3430         case EQ_OP :
3431             optExpr = newAst_VALUE(constVal("1"));
3432             break;
3433         }
3434
3435         return decorateType(optExpr);
3436     }
3437
3438     vleft = (root->left->type == EX_VALUE ?
3439              root->left->opval.val : NULL );
3440     
3441     vright = (root->right->type == EX_VALUE ?
3442               root->right->opval.val : NULL);
3443     
3444     /* if left is a BITVAR in BITSPACE */
3445     /* and right is a LITERAL then opt-*/
3446     /* imize else do nothing               */
3447     if (vleft && vright                   &&
3448         IS_BITVAR(vleft->etype)           && 
3449         IN_BITSPACE(SPEC_OCLS(vleft->etype))  &&
3450         IS_LITERAL(vright->etype)) {
3451         
3452         /* if right side > 1 then comparison may never succeed */
3453         if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3454             werror(W_BAD_COMPARE);
3455             goto noOptimize ;
3456         }
3457         
3458         if ( litValue ) {
3459             switch (root->opval.op) {
3460             case '>' :  /* bit value greater than 1 cannot be */
3461                 werror(W_BAD_COMPARE);
3462                 goto noOptimize ;
3463                 break;
3464                 
3465             case '<' : /* bit value < 1 means 0 */
3466             case NE_OP :
3467                 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3468                 break;
3469                 
3470             case LE_OP : /* bit value <= 1 means no check */
3471                 optExpr = newAst_VALUE(vright);         
3472                 break;
3473                 
3474             case GE_OP : /* bit value >= 1 means only check for = */
3475             case EQ_OP :
3476                 optExpr = newAst_VALUE(vleft);          
3477                 break;
3478             }
3479         } else { /* literal is zero */
3480             switch (root->opval.op) {
3481             case '<' :  /* bit value < 0 cannot be */
3482                 werror(W_BAD_COMPARE);
3483                 goto noOptimize ;
3484                 break;
3485                 
3486             case '>' : /* bit value > 0 means 1 */
3487             case NE_OP :
3488                 optExpr = newAst_VALUE(vleft);       
3489                 break;
3490                 
3491             case LE_OP : /* bit value <= 0 means no check */
3492             case GE_OP : /* bit value >= 0 means no check */
3493                 werror(W_BAD_COMPARE);
3494                 goto noOptimize ;
3495                 break;
3496                 
3497             case EQ_OP : /* bit == 0 means ! of bit */
3498                 optExpr = newNode('!',newAst_VALUE(vleft),NULL);              
3499                 break;
3500             }
3501         }                      
3502         return decorateType(resolveSymbols(optExpr)); 
3503     }   /* end-of-if of BITVAR */
3504     
3505     noOptimize :
3506         return root;
3507 }
3508 /*-----------------------------------------------------------------*/
3509 /* addSymToBlock : adds the symbol to the first block we find      */
3510 /*-----------------------------------------------------------------*/
3511 void addSymToBlock (symbol *sym, ast *tree)
3512 {
3513     /* reached end of tree or a leaf */
3514     if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3515         return ;
3516
3517     /* found a block */
3518     if (IS_AST_OP(tree) &&
3519         tree->opval.op == BLOCK ) {
3520         
3521         symbol *lsym = copySymbol(sym);
3522         
3523         lsym->next = AST_VALUES(tree,sym);
3524         AST_VALUES(tree,sym) = lsym ;
3525         return ;
3526     }
3527     
3528     addSymToBlock(sym,tree->left);
3529     addSymToBlock(sym,tree->right);
3530 }
3531
3532 /*-----------------------------------------------------------------*/
3533 /* processRegParms - do processing for register parameters         */
3534 /*-----------------------------------------------------------------*/
3535 static void processRegParms (value *args, ast *body)
3536 {
3537     while (args) {
3538         if (IS_REGPARM(args->etype))
3539             addSymToBlock(args->sym,body);
3540         args = args->next;
3541     }
3542 }
3543
3544 /*-----------------------------------------------------------------*/
3545 /* resetParmKey - resets the operandkeys for the symbols           */
3546 /*-----------------------------------------------------------------*/
3547 DEFSETFUNC(resetParmKey)
3548 {
3549     symbol *sym = item;
3550
3551     sym->key = 0 ;
3552     sym->defs = NULL ;
3553     sym->uses = NULL ;
3554     sym->remat= 0;
3555     return 1;
3556 }
3557
3558 /*-----------------------------------------------------------------*/
3559 /* createFunction - This is the key node that calls the iCode for  */
3560 /*                  generating the code for a function. Note code  */
3561 /*                  is generated function by function, later when  */
3562 /*                  add inter-procedural analysis this will change */
3563 /*-----------------------------------------------------------------*/
3564 ast  *createFunction   (symbol  *name,   ast  *body )
3565 {
3566     ast  *ex ;
3567     symbol *csym;
3568     int stack = 0 ;
3569     link *fetype;       
3570     iCode *piCode = NULL;
3571     
3572     /* if check function return 0 then some problem */
3573     if (checkFunction (name) == 0)
3574         return NULL;
3575     
3576     /* create a dummy block if none exists */
3577     if (!body)
3578         body = newNode(BLOCK,NULL,NULL);
3579
3580     noLineno++ ;
3581    
3582     /* check if the function name already in the symbol table */
3583     if ((csym = findSym (SymbolTab,NULL,name->name))) {
3584         name = csym ;     
3585         /* special case for compiler defined functions
3586            we need to add the name to the publics list : this
3587            actually means we are now compiling the compiler
3588            support routine */
3589         if (name->cdef) {
3590             addSet(&publics,name);
3591         }
3592     }
3593     else {
3594         addSymChain(name);
3595         allocVariables(name);
3596     }
3597     name->lastLine = yylineno;
3598     currFunc = name ;
3599     processFuncArgs(currFunc,0);
3600     
3601     /* set the stack pointer */
3602     /* PENDING: check this for the mcs51 */
3603     stackPtr = -port->stack.direction * port->stack.call_overhead;
3604     if (IS_ISR(name->etype))
3605         stackPtr -= port->stack.direction * port->stack.isr_overhead;
3606     if (IS_RENT(name->etype) || options.stackAuto)
3607         stackPtr -= port->stack.direction * port->stack.reent_overhead;
3608
3609     xstackPtr = -port->stack.direction * port->stack.call_overhead;
3610     
3611     fetype = getSpec(name->type); /* get the specifier for the function */
3612     /* if this is a reentrant function then */
3613     if (IS_RENT(fetype))
3614         reentrant++ ;
3615         
3616     allocParms (name->args);           /* allocate the parameters */
3617
3618     /* do processing for parameters that are passed in registers */
3619     processRegParms (name->args,body); 
3620
3621    /* set the stack pointer */
3622     stackPtr = 0;
3623     xstackPtr= -1;
3624     
3625     /* allocate & autoinit the block variables */
3626     processBlockVars (body, &stack,ALLOCATE); 
3627     
3628     /* save the stack information */
3629     if (options.useXstack)
3630         name->xstack = SPEC_STAK(fetype) = stack;
3631     else
3632         name->stack = SPEC_STAK(fetype) = stack;
3633     
3634     /* name needs to be mangled */
3635     sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3636     
3637     body = resolveSymbols(body); /* resolve the symbols */
3638     body = decorateType (body);  /* propagateType & do semantic checks */
3639     
3640     ex = newAst_VALUE(symbolVal(name));    /* create name       */
3641     ex = newNode (FUNCTION,ex,body);
3642     ex->values.args = name->args ;
3643     
3644     if (fatalError) {
3645         werror(E_FUNC_NO_CODE,name->name);
3646         goto skipall ;
3647     }
3648         
3649     /* create the node & generate intermediate code */  
3650     codeOutFile = code->oFile;
3651     piCode = iCodeFromAst(ex);
3652
3653      if (fatalError) {
3654          werror(E_FUNC_NO_CODE,name->name);
3655          goto skipall ;
3656      }
3657      
3658      eBBlockFromiCode(piCode);
3659                     
3660     /* if there are any statics then do them */
3661     if (staticAutos) {
3662         codeOutFile = statsg->oFile;
3663         eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3664         staticAutos = NULL;
3665     }
3666     
3667  skipall:
3668     
3669     /* dealloc the block variables */
3670     processBlockVars(body, &stack,DEALLOCATE);
3671     /* deallocate paramaters */
3672     deallocParms(name->args);
3673     
3674     if (IS_RENT(fetype))
3675         reentrant-- ;
3676     
3677     /* we are done freeup memory & cleanup */
3678     noLineno-- ;
3679     labelKey = 1 ;
3680     name->key = 0;
3681     name->fbody = 1;
3682     addSet(&operKeyReset,name);
3683     applyToSet(operKeyReset,resetParmKey);
3684        
3685     if (options.debug && !options.nodebug)
3686         cdbStructBlock(1,cdbFile);
3687
3688     cleanUpLevel(LabelTab,0);
3689     cleanUpBlock(StructTab,1);
3690     cleanUpBlock(TypedefTab,1);
3691
3692     xstack->syms = NULL;
3693     istack->syms = NULL;
3694     return NULL ;
3695 }
3696
3697