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