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