1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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
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.
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.
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 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
74 newAst (int type, void *op)
77 static int oldLineno = 0;
79 Safe_calloc (1, ex, sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : yylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
88 /* depending on the type */
92 ex->opval.val = (value *) op;
95 ex->opval.op = (long) op;
98 ex->opval.lnk = (sym_link *) op;
101 ex->opval.stmnt = (unsigned) op;
109 newAst_ (unsigned type)
112 static int oldLineno = 0;
114 ex = Safe_calloc (1, sizeof (ast));
117 ex->lineno = (noLineno ? oldLineno : yylineno);
118 ex->filename = currFname;
119 ex->level = NestLevel;
120 ex->block = currBlockno;
121 ex->initMode = inInitMode;
126 newAst_VALUE (value * val)
128 ast *ex = newAst_ (EX_VALUE);
134 newAst_OP (unsigned op)
136 ast *ex = newAst_ (EX_OP);
142 newAst_LINK (sym_link * val)
144 ast *ex = newAst_ (EX_LINK);
150 newAst_STMNT (unsigned val)
152 ast *ex = newAst_ (EX_STMNT);
153 ex->opval.stmnt = val;
157 /*-----------------------------------------------------------------*/
158 /* newNode - creates a new node */
159 /*-----------------------------------------------------------------*/
161 newNode (long op, ast * left, ast * right)
172 /*-----------------------------------------------------------------*/
173 /* newIfxNode - creates a new Ifx Node */
174 /*-----------------------------------------------------------------*/
176 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
180 /* if this is a literal then we already know the result */
181 if (condAst->etype && IS_LITERAL (condAst->etype))
184 /* then depending on the expression value */
185 if (floatFromVal (condAst->opval.val))
186 ifxNode = newNode (GOTO,
187 newAst_VALUE (symbolVal (trueLabel)),
190 ifxNode = newNode (GOTO,
191 newAst_VALUE (symbolVal (falseLabel)),
196 ifxNode = newNode (IFX, condAst, NULL);
197 ifxNode->trueLabel = trueLabel;
198 ifxNode->falseLabel = falseLabel;
204 /*-----------------------------------------------------------------*/
205 /* copyAstValues - copies value portion of ast if needed */
206 /*-----------------------------------------------------------------*/
208 copyAstValues (ast * dest, ast * src)
210 switch (src->opval.op)
213 dest->values.sym = copySymbolChain (src->values.sym);
217 dest->values.switchVals.swVals =
218 copyValue (src->values.switchVals.swVals);
219 dest->values.switchVals.swDefault =
220 src->values.switchVals.swDefault;
221 dest->values.switchVals.swNum =
222 src->values.switchVals.swNum;
226 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
227 strcpy (dest->values.inlineasm, src->values.inlineasm);
230 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
231 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
232 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
233 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
234 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
235 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
236 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
241 /*-----------------------------------------------------------------*/
242 /* copyAst - makes a copy of a given astession */
243 /*-----------------------------------------------------------------*/
252 dest = Safe_calloc (1, sizeof (ast));
254 dest->type = src->type;
255 dest->lineno = src->lineno;
256 dest->level = src->level;
257 dest->funcName = src->funcName;
258 dest->argSym = src->argSym;
260 /* if this is a leaf */
262 if (src->type == EX_VALUE)
264 dest->opval.val = copyValue (src->opval.val);
269 if (src->type == EX_LINK)
271 dest->opval.lnk = copyLinkChain (src->opval.lnk);
275 dest->opval.op = src->opval.op;
277 /* if this is a node that has special values */
278 copyAstValues (dest, src);
281 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
283 dest->trueLabel = copySymbol (src->trueLabel);
284 dest->falseLabel = copySymbol (src->falseLabel);
285 dest->left = copyAst (src->left);
286 dest->right = copyAst (src->right);
292 /*-----------------------------------------------------------------*/
293 /* hasSEFcalls - returns TRUE if tree has a function call */
294 /*-----------------------------------------------------------------*/
296 hasSEFcalls (ast * tree)
301 if (tree->type == EX_OP &&
302 (tree->opval.op == CALL ||
303 tree->opval.op == PCALL ||
304 tree->opval.op == '=' ||
305 tree->opval.op == INC_OP ||
306 tree->opval.op == DEC_OP))
309 return (hasSEFcalls (tree->left) |
310 hasSEFcalls (tree->right));
313 /*-----------------------------------------------------------------*/
314 /* isAstEqual - compares two asts & returns 1 if they are equal */
315 /*-----------------------------------------------------------------*/
317 isAstEqual (ast * t1, ast * t2)
326 if (t1->type != t2->type)
332 if (t1->opval.op != t2->opval.op)
334 return (isAstEqual (t1->left, t2->left) &&
335 isAstEqual (t1->right, t2->right));
339 if (t1->opval.val->sym)
341 if (!t2->opval.val->sym)
344 return isSymbolEqual (t1->opval.val->sym,
349 if (t2->opval.val->sym)
352 return (floatFromVal (t1->opval.val) ==
353 floatFromVal (t2->opval.val));
357 /* only compare these two types */
365 /*-----------------------------------------------------------------*/
366 /* resolveSymbols - resolve symbols from the symbol table */
367 /*-----------------------------------------------------------------*/
369 resolveSymbols (ast * tree)
371 /* walk the entire tree and check for values */
372 /* with symbols if we find one then replace */
373 /* symbol with that from the symbol table */
379 /* if not block & function */
380 if (tree->type == EX_OP &&
381 (tree->opval.op != FUNCTION &&
382 tree->opval.op != BLOCK &&
383 tree->opval.op != NULLOP))
385 filename = tree->filename;
386 lineno = tree->lineno;
389 /* make sure we resolve the true & false labels for ifx */
390 if (tree->type == EX_OP && tree->opval.op == IFX)
396 if ((csym = findSym (LabelTab, tree->trueLabel,
397 tree->trueLabel->name)))
398 tree->trueLabel = csym;
400 werror (E_LABEL_UNDEF, tree->trueLabel->name);
403 if (tree->falseLabel)
405 if ((csym = findSym (LabelTab,
407 tree->falseLabel->name)))
408 tree->falseLabel = csym;
410 werror (E_LABEL_UNDEF, tree->falseLabel->name);
415 /* if this is a label resolve it from the labelTab */
416 if (IS_AST_VALUE (tree) &&
417 tree->opval.val->sym &&
418 tree->opval.val->sym->islbl)
421 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
422 tree->opval.val->sym->name);
425 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
427 tree->opval.val->sym = csym;
429 goto resolveChildren;
432 /* do only for leafs */
433 if (IS_AST_VALUE (tree) &&
434 tree->opval.val->sym &&
435 !tree->opval.val->sym->implicit)
438 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
440 /* if found in the symbol table & they r not the same */
441 if (csym && tree->opval.val->sym != csym)
443 tree->opval.val->sym = csym;
444 tree->opval.val->type = csym->type;
445 tree->opval.val->etype = csym->etype;
448 /* if not found in the symbol table */
449 /* mark it as undefined assume it is */
450 /* an integer in data space */
451 if (!csym && !tree->opval.val->sym->implicit)
454 /* if this is a function name then */
455 /* mark it as returning an int */
458 tree->opval.val->sym->type = newLink ();
459 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
460 tree->opval.val->sym->type->next =
461 tree->opval.val->sym->etype = newIntLink ();
462 tree->opval.val->etype = tree->opval.val->etype;
463 tree->opval.val->type = tree->opval.val->sym->type;
464 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
468 tree->opval.val->sym->undefined = 1;
469 tree->opval.val->type =
470 tree->opval.val->etype = newIntLink ();
471 tree->opval.val->sym->type =
472 tree->opval.val->sym->etype = newIntLink ();
478 resolveSymbols (tree->left);
479 resolveSymbols (tree->right);
484 /*-----------------------------------------------------------------*/
485 /* setAstLineno - walks a ast tree & sets the line number */
486 /*-----------------------------------------------------------------*/
488 setAstLineno (ast * tree, int lineno)
493 tree->lineno = lineno;
494 setAstLineno (tree->left, lineno);
495 setAstLineno (tree->right, lineno);
500 /* this functions seems to be superfluous?! kmh */
502 /*-----------------------------------------------------------------*/
503 /* resolveFromTable - will return the symbal table value */
504 /*-----------------------------------------------------------------*/
506 resolveFromTable (value * val)
513 csym = findSymWithLevel (SymbolTab, val->sym);
515 /* if found in the symbol table & they r not the same */
516 if (csym && val->sym != csym &&
517 csym->level == val->sym->level &&
523 val->type = csym->type;
524 val->etype = csym->etype;
531 /*-----------------------------------------------------------------*/
532 /* funcOfType :- function of type with name */
533 /*-----------------------------------------------------------------*/
535 funcOfType (char *name, sym_link * type, sym_link * argType,
539 /* create the symbol */
540 sym = newSymbol (name, 0);
542 /* if arguments required */
547 args = sym->args = newValue ();
551 args->type = copyLinkChain (argType);
552 args->etype = getSpec (args->type);
555 args = args->next = newValue ();
559 /* setup return value */
560 sym->type = newLink ();
561 DCL_TYPE (sym->type) = FUNCTION;
562 sym->type->next = copyLinkChain (type);
563 sym->etype = getSpec (sym->type);
564 SPEC_RENT (sym->etype) = rent;
569 allocVariables (sym);
574 /*-----------------------------------------------------------------*/
575 /* reverseParms - will reverse a parameter tree */
576 /*-----------------------------------------------------------------*/
578 reverseParms (ast * ptree)
584 /* top down if we find a nonParm tree then quit */
585 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
588 ptree->left = ptree->right;
589 ptree->right = ttree;
590 reverseParms (ptree->left);
591 reverseParms (ptree->right);
597 /*-----------------------------------------------------------------*/
598 /* processParms - makes sure the parameters are okay and do some */
599 /* processing with them */
600 /*-----------------------------------------------------------------*/
602 processParms (ast * func,
608 sym_link *fetype = func->etype;
610 /* if none of them exist */
611 if (!defParm && !actParm)
614 /* if the function is being called via a pointer & */
615 /* it has not been defined a reentrant then we cannot */
616 /* have parameters */
617 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
619 werror (E_NONRENT_ARGS);
623 /* if defined parameters ended but actual parameters */
624 /* exist and this is not defined as a variable arg */
625 /* also check if statckAuto option is specified */
626 if ((!defParm) && actParm && (!func->hasVargs) &&
627 !options.stackAuto && !IS_RENT (fetype))
629 werror (E_TOO_MANY_PARMS);
633 /* if defined parameters present but no actual parameters */
634 if (defParm && !actParm)
636 werror (E_TOO_FEW_PARMS);
640 /* If this is a varargs function... */
641 if (!defParm && actParm && func->hasVargs)
645 if (IS_CAST_OP (actParm)
646 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
648 /* Parameter was explicitly typecast; don't touch it. */
652 /* If it's a small integer, upcast to int. */
653 if (IS_INTEGRAL (actParm->ftype)
654 && getSize (actParm->ftype) < (unsigned) INTSIZE)
656 newType = newAst_LINK (INTTYPE);
659 if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
661 newType = newAst_LINK (copyLinkChain (actParm->ftype));
662 DCL_TYPE (newType->opval.lnk) = GPOINTER;
665 if (IS_AGGREGATE (actParm->ftype))
667 newType = newAst_LINK (copyLinkChain (actParm->ftype));
668 DCL_TYPE (newType->opval.lnk) = GPOINTER;
673 /* cast required; change this op to a cast. */
674 ast *parmCopy = resolveSymbols (copyAst (actParm));
676 actParm->type = EX_OP;
677 actParm->opval.op = CAST;
678 actParm->left = newType;
679 actParm->right = parmCopy;
680 decorateType (actParm);
682 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
684 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
685 processParms (func, NULL, actParm->right, parmNumber, rightmost));
690 /* if defined parameters ended but actual has not & */
692 if (!defParm && actParm &&
693 (options.stackAuto || IS_RENT (fetype)))
696 resolveSymbols (actParm);
697 /* if this is a PARAM node then match left & right */
698 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
700 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
701 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
705 /* If we have found a value node by following only right-hand links,
706 * then we know that there are no more values after us.
708 * Therefore, if there are more defined parameters, the caller didn't
711 if (rightmost && defParm->next)
713 werror (E_TOO_FEW_PARMS);
718 /* the parameter type must be at least castable */
719 if (checkType (defParm->type, actParm->ftype) == 0)
721 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
722 werror (E_CONTINUE, "defined type ");
723 printTypeChain (defParm->type, stderr);
724 fprintf (stderr, "\n");
725 werror (E_CONTINUE, "actual type ");
726 printTypeChain (actParm->ftype, stderr);
727 fprintf (stderr, "\n");
730 /* if the parameter is castable then add the cast */
731 if (checkType (defParm->type, actParm->ftype) < 0)
733 ast *pTree = resolveSymbols (copyAst (actParm));
735 /* now change the current one to a cast */
736 actParm->type = EX_OP;
737 actParm->opval.op = CAST;
738 actParm->left = newAst_LINK (defParm->type);
739 actParm->right = pTree;
740 actParm->etype = defParm->etype;
741 actParm->ftype = defParm->type;
744 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
746 actParm->argSym = defParm->sym;
747 /* make a copy and change the regparm type to the defined parm */
748 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
749 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
753 /*-----------------------------------------------------------------*/
754 /* createIvalType - generates ival for basic types */
755 /*-----------------------------------------------------------------*/
757 createIvalType (ast * sym, sym_link * type, initList * ilist)
761 /* if initList is deep */
762 if (ilist->type == INIT_DEEP)
763 ilist = ilist->init.deep;
765 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
766 return decorateType (newNode ('=', sym, iExpr));
769 /*-----------------------------------------------------------------*/
770 /* createIvalStruct - generates initial value for structures */
771 /*-----------------------------------------------------------------*/
773 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
779 sflds = SPEC_STRUCT (type)->fields;
780 if (ilist->type != INIT_DEEP)
782 werror (E_INIT_STRUCT, "");
786 iloop = ilist->init.deep;
788 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
792 /* if we have come to end */
796 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
797 lAst = decorateType (resolveSymbols (lAst));
798 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
804 /*-----------------------------------------------------------------*/
805 /* createIvalArray - generates code for array initialization */
806 /*-----------------------------------------------------------------*/
808 createIvalArray (ast * sym, sym_link * type, initList * ilist)
812 int lcnt = 0, size = 0;
814 /* take care of the special case */
815 /* array of characters can be init */
817 if (IS_CHAR (type->next))
818 if ((rast = createIvalCharPtr (sym,
820 decorateType (resolveSymbols (list2expr (ilist))))))
822 return decorateType (resolveSymbols (rast));
824 /* not the special case */
825 if (ilist->type != INIT_DEEP)
827 werror (E_INIT_STRUCT, "");
831 iloop = ilist->init.deep;
832 lcnt = DCL_ELEM (type);
839 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
840 aSym = decorateType (resolveSymbols (aSym));
841 rast = createIval (aSym, type->next, iloop, rast);
842 iloop = (iloop ? iloop->next : NULL);
845 /* if not array limits given & we */
846 /* are out of initialisers then */
847 if (!DCL_ELEM (type) && !iloop)
850 /* no of elements given and we */
851 /* have generated for all of them */
856 /* if we have not been given a size */
857 if (!DCL_ELEM (type))
858 DCL_ELEM (type) = size;
860 return decorateType (resolveSymbols (rast));
864 /*-----------------------------------------------------------------*/
865 /* createIvalCharPtr - generates initial values for char pointers */
866 /*-----------------------------------------------------------------*/
868 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
872 /* if this is a pointer & right is a literal array then */
873 /* just assignment will do */
874 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
875 SPEC_SCLS (iexpr->etype) == S_CODE)
876 && IS_ARRAY (iexpr->ftype)))
877 return newNode ('=', sym, iexpr);
879 /* left side is an array so we have to assign each */
881 if ((IS_LITERAL (iexpr->etype) ||
882 SPEC_SCLS (iexpr->etype) == S_CODE)
883 && IS_ARRAY (iexpr->ftype))
886 /* for each character generate an assignment */
887 /* to the array element */
888 char *s = SPEC_CVAL (iexpr->etype).v_char;
893 rast = newNode (NULLOP,
897 newAst_VALUE (valueFromLit ((float) i))),
898 newAst_VALUE (valueFromLit (*s))));
902 rast = newNode (NULLOP,
906 newAst_VALUE (valueFromLit ((float) i))),
907 newAst_VALUE (valueFromLit (*s))));
908 return decorateType (resolveSymbols (rast));
914 /*-----------------------------------------------------------------*/
915 /* createIvalPtr - generates initial value for pointers */
916 /*-----------------------------------------------------------------*/
918 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
924 if (ilist->type == INIT_DEEP)
925 ilist = ilist->init.deep;
927 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
929 /* if character pointer */
930 if (IS_CHAR (type->next))
931 if ((rast = createIvalCharPtr (sym, type, iexpr)))
934 return newNode ('=', sym, iexpr);
937 /*-----------------------------------------------------------------*/
938 /* createIval - generates code for initial value */
939 /*-----------------------------------------------------------------*/
941 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
948 /* if structure then */
949 if (IS_STRUCT (type))
950 rast = createIvalStruct (sym, type, ilist);
952 /* if this is a pointer */
954 rast = createIvalPtr (sym, type, ilist);
956 /* if this is an array */
958 rast = createIvalArray (sym, type, ilist);
960 /* if type is SPECIFIER */
962 rast = createIvalType (sym, type, ilist);
964 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
966 return decorateType (resolveSymbols (rast));
969 /*-----------------------------------------------------------------*/
970 /* initAggregates - initialises aggregate variables with initv */
971 /*-----------------------------------------------------------------*/
973 initAggregates (symbol * sym, initList * ival, ast * wid)
975 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
978 /*-----------------------------------------------------------------*/
979 /* gatherAutoInit - creates assignment expressions for initial */
981 /*-----------------------------------------------------------------*/
983 gatherAutoInit (symbol * autoChain)
990 for (sym = autoChain; sym; sym = sym->next)
993 /* resolve the symbols in the ival */
995 resolveIvalSym (sym->ival);
997 /* if this is a static variable & has an */
998 /* initial value the code needs to be lifted */
999 /* here to the main portion since they can be */
1000 /* initialised only once at the start */
1001 if (IS_STATIC (sym->etype) && sym->ival &&
1002 SPEC_SCLS (sym->etype) != S_CODE)
1006 /* insert the symbol into the symbol table */
1007 /* with level = 0 & name = rname */
1008 newSym = copySymbol (sym);
1009 addSym (SymbolTab, newSym, newSym->name, 0, 0);
1011 /* now lift the code to main */
1012 if (IS_AGGREGATE (sym->type))
1013 work = initAggregates (sym, sym->ival, NULL);
1015 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1016 list2expr (sym->ival));
1018 setAstLineno (work, sym->lineDef);
1022 staticAutos = newNode (NULLOP, staticAutos, work);
1029 /* if there is an initial value */
1030 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1032 if (IS_AGGREGATE (sym->type))
1033 work = initAggregates (sym, sym->ival, NULL);
1035 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1036 list2expr (sym->ival));
1038 setAstLineno (work, sym->lineDef);
1041 init = newNode (NULLOP, init, work);
1050 /*-----------------------------------------------------------------*/
1051 /* stringToSymbol - creates a symbol from a literal string */
1052 /*-----------------------------------------------------------------*/
1054 stringToSymbol (value * val)
1056 char name[SDCC_NAME_MAX + 1];
1057 static int charLbl = 0;
1060 sprintf (name, "_str_%d", charLbl++);
1061 sym = newSymbol (name, 0); /* make it @ level 0 */
1062 strcpy (sym->rname, name);
1064 /* copy the type from the value passed */
1065 sym->type = copyLinkChain (val->type);
1066 sym->etype = getSpec (sym->type);
1067 /* change to storage class & output class */
1068 SPEC_SCLS (sym->etype) = S_CODE;
1069 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1070 SPEC_STAT (sym->etype) = 1;
1071 /* make the level & block = 0 */
1072 sym->block = sym->level = 0;
1074 /* create an ival */
1075 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1080 allocVariables (sym);
1083 return symbolVal (sym);
1087 /*-----------------------------------------------------------------*/
1088 /* processBlockVars - will go thru the ast looking for block if */
1089 /* a block is found then will allocate the syms */
1090 /* will also gather the auto inits present */
1091 /*-----------------------------------------------------------------*/
1093 processBlockVars (ast * tree, int *stack, int action)
1098 /* if this is a block */
1099 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1103 if (action == ALLOCATE)
1105 autoInit = gatherAutoInit (tree->values.sym);
1106 *stack += allocVariables (tree->values.sym);
1108 /* if there are auto inits then do them */
1110 tree->left = newNode (NULLOP, autoInit, tree->left);
1112 else /* action is deallocate */
1113 deallocLocal (tree->values.sym);
1116 processBlockVars (tree->left, stack, action);
1117 processBlockVars (tree->right, stack, action);
1121 /*-----------------------------------------------------------------*/
1122 /* constExprValue - returns the value of a constant expression */
1123 /*-----------------------------------------------------------------*/
1125 constExprValue (ast * cexpr, int check)
1127 cexpr = decorateType (resolveSymbols (cexpr));
1129 /* if this is not a constant then */
1130 if (!IS_LITERAL (cexpr->ftype))
1132 /* then check if this is a literal array
1134 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1135 SPEC_CVAL (cexpr->etype).v_char &&
1136 IS_ARRAY (cexpr->ftype))
1138 value *val = valFromType (cexpr->ftype);
1139 SPEC_SCLS (val->etype) = S_LITERAL;
1140 val->sym = cexpr->opval.val->sym;
1141 val->sym->type = copyLinkChain (cexpr->ftype);
1142 val->sym->etype = getSpec (val->sym->type);
1143 strcpy (val->name, cexpr->opval.val->sym->rname);
1147 /* if we are casting a literal value then */
1148 if (IS_AST_OP (cexpr) &&
1149 cexpr->opval.op == CAST &&
1150 IS_LITERAL (cexpr->left->ftype))
1151 return valCastLiteral (cexpr->ftype,
1152 floatFromVal (cexpr->left->opval.val));
1154 if (IS_AST_VALUE (cexpr))
1155 return cexpr->opval.val;
1158 werror (E_CONST_EXPECTED, "found expression");
1163 /* return the value */
1164 return cexpr->opval.val;
1168 /*-----------------------------------------------------------------*/
1169 /* isLabelInAst - will return true if a given label is found */
1170 /*-----------------------------------------------------------------*/
1172 isLabelInAst (symbol * label, ast * tree)
1174 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1177 if (IS_AST_OP (tree) &&
1178 tree->opval.op == LABEL &&
1179 isSymbolEqual (AST_SYMBOL (tree->left), label))
1182 return isLabelInAst (label, tree->right) &&
1183 isLabelInAst (label, tree->left);
1187 /*-----------------------------------------------------------------*/
1188 /* isLoopCountable - return true if the loop count can be determi- */
1189 /* -ned at compile time . */
1190 /*-----------------------------------------------------------------*/
1192 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1193 symbol ** sym, ast ** init, ast ** end)
1196 /* the loop is considered countable if the following
1197 conditions are true :-
1199 a) initExpr :- <sym> = <const>
1200 b) condExpr :- <sym> < <const1>
1201 c) loopExpr :- <sym> ++
1204 /* first check the initExpr */
1205 if (IS_AST_OP (initExpr) &&
1206 initExpr->opval.op == '=' && /* is assignment */
1207 IS_AST_SYM_VALUE (initExpr->left))
1208 { /* left is a symbol */
1210 *sym = AST_SYMBOL (initExpr->left);
1211 *init = initExpr->right;
1216 /* for now the symbol has to be of
1218 if (!IS_INTEGRAL ((*sym)->type))
1221 /* now check condExpr */
1222 if (IS_AST_OP (condExpr))
1225 switch (condExpr->opval.op)
1228 if (IS_AST_SYM_VALUE (condExpr->left) &&
1229 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1230 IS_AST_LIT_VALUE (condExpr->right))
1232 *end = condExpr->right;
1238 if (IS_AST_OP (condExpr->left) &&
1239 condExpr->left->opval.op == '>' &&
1240 IS_AST_LIT_VALUE (condExpr->left->right) &&
1241 IS_AST_SYM_VALUE (condExpr->left->left) &&
1242 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1245 *end = newNode ('+', condExpr->left->right,
1246 newAst_VALUE (constVal ("1")));
1257 /* check loop expression is of the form <sym>++ */
1258 if (!IS_AST_OP (loopExpr))
1261 /* check if <sym> ++ */
1262 if (loopExpr->opval.op == INC_OP)
1268 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1269 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1276 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1277 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1285 if (loopExpr->opval.op == ADD_ASSIGN)
1288 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1289 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1290 IS_AST_LIT_VALUE (loopExpr->right) &&
1291 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1299 /*-----------------------------------------------------------------*/
1300 /* astHasVolatile - returns true if ast contains any volatile */
1301 /*-----------------------------------------------------------------*/
1303 astHasVolatile (ast * tree)
1308 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1311 if (IS_AST_OP (tree))
1312 return astHasVolatile (tree->left) ||
1313 astHasVolatile (tree->right);
1318 /*-----------------------------------------------------------------*/
1319 /* astHasPointer - return true if the ast contains any ptr variable */
1320 /*-----------------------------------------------------------------*/
1322 astHasPointer (ast * tree)
1327 if (IS_AST_LINK (tree))
1330 /* if we hit an array expression then check
1331 only the left side */
1332 if (IS_AST_OP (tree) && tree->opval.op == '[')
1333 return astHasPointer (tree->left);
1335 if (IS_AST_VALUE (tree))
1336 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1338 return astHasPointer (tree->left) ||
1339 astHasPointer (tree->right);
1343 /*-----------------------------------------------------------------*/
1344 /* astHasSymbol - return true if the ast has the given symbol */
1345 /*-----------------------------------------------------------------*/
1347 astHasSymbol (ast * tree, symbol * sym)
1349 if (!tree || IS_AST_LINK (tree))
1352 if (IS_AST_VALUE (tree))
1354 if (IS_AST_SYM_VALUE (tree))
1355 return isSymbolEqual (AST_SYMBOL (tree), sym);
1360 return astHasSymbol (tree->left, sym) ||
1361 astHasSymbol (tree->right, sym);
1364 /*-----------------------------------------------------------------*/
1365 /* isConformingBody - the loop body has to conform to a set of rules */
1366 /* for the loop to be considered reversible read on for rules */
1367 /*-----------------------------------------------------------------*/
1369 isConformingBody (ast * pbody, symbol * sym, ast * body)
1372 /* we are going to do a pre-order traversal of the
1373 tree && check for the following conditions. (essentially
1374 a set of very shallow tests )
1375 a) the sym passed does not participate in
1376 any arithmetic operation
1377 b) There are no function calls
1378 c) all jumps are within the body
1379 d) address of loop control variable not taken
1380 e) if an assignment has a pointer on the
1381 left hand side make sure right does not have
1382 loop control variable */
1384 /* if we reach the end or a leaf then true */
1385 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1389 /* if anything else is "volatile" */
1390 if (IS_VOLATILE (TETYPE (pbody)))
1393 /* we will walk the body in a pre-order traversal for
1395 switch (pbody->opval.op)
1397 /*------------------------------------------------------------------*/
1399 return isConformingBody (pbody->right, sym, body);
1401 /*------------------------------------------------------------------*/
1406 /*------------------------------------------------------------------*/
1407 case INC_OP: /* incerement operator unary so left only */
1410 /* sure we are not sym is not modified */
1412 IS_AST_SYM_VALUE (pbody->left) &&
1413 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1417 IS_AST_SYM_VALUE (pbody->right) &&
1418 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1423 /*------------------------------------------------------------------*/
1425 case '*': /* can be unary : if right is null then unary operation */
1430 /* if right is NULL then unary operation */
1431 /*------------------------------------------------------------------*/
1432 /*----------------------------*/
1434 /*----------------------------*/
1437 if (IS_AST_SYM_VALUE (pbody->left) &&
1438 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1441 return isConformingBody (pbody->left, sym, body);
1445 if (astHasSymbol (pbody->left, sym) ||
1446 astHasSymbol (pbody->right, sym))
1451 /*------------------------------------------------------------------*/
1459 if (IS_AST_SYM_VALUE (pbody->left) &&
1460 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1463 if (IS_AST_SYM_VALUE (pbody->right) &&
1464 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1467 return isConformingBody (pbody->left, sym, body) &&
1468 isConformingBody (pbody->right, sym, body);
1475 if (IS_AST_SYM_VALUE (pbody->left) &&
1476 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1478 return isConformingBody (pbody->left, sym, body);
1480 /*------------------------------------------------------------------*/
1492 case SIZEOF: /* evaluate wihout code generation */
1494 return isConformingBody (pbody->left, sym, body) &&
1495 isConformingBody (pbody->right, sym, body);
1497 /*------------------------------------------------------------------*/
1500 /* if left has a pointer & right has loop
1501 control variable then we cannot */
1502 if (astHasPointer (pbody->left) &&
1503 astHasSymbol (pbody->right, sym))
1505 if (astHasVolatile (pbody->left))
1508 if (IS_AST_SYM_VALUE (pbody->left) &&
1509 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1512 if (astHasVolatile (pbody->left))
1515 return isConformingBody (pbody->left, sym, body) &&
1516 isConformingBody (pbody->right, sym, body);
1527 assert ("Parser should not have generated this\n");
1529 /*------------------------------------------------------------------*/
1530 /*----------------------------*/
1531 /* comma operator */
1532 /*----------------------------*/
1534 return isConformingBody (pbody->left, sym, body) &&
1535 isConformingBody (pbody->right, sym, body);
1537 /*------------------------------------------------------------------*/
1538 /*----------------------------*/
1540 /*----------------------------*/
1544 /*------------------------------------------------------------------*/
1545 /*----------------------------*/
1546 /* return statement */
1547 /*----------------------------*/
1552 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1557 if (astHasSymbol (pbody->left, sym))
1564 return isConformingBody (pbody->left, sym, body) &&
1565 isConformingBody (pbody->right, sym, body);
1571 /*-----------------------------------------------------------------*/
1572 /* isLoopReversible - takes a for loop as input && returns true */
1573 /* if the for loop is reversible. If yes will set the value of */
1574 /* the loop control var & init value & termination value */
1575 /*-----------------------------------------------------------------*/
1577 isLoopReversible (ast * loop, symbol ** loopCntrl,
1578 ast ** init, ast ** end)
1580 /* if option says don't do it then don't */
1581 if (optimize.noLoopReverse)
1583 /* there are several tests to determine this */
1585 /* for loop has to be of the form
1586 for ( <sym> = <const1> ;
1587 [<sym> < <const2>] ;
1588 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1590 if (!isLoopCountable (AST_FOR (loop, initExpr),
1591 AST_FOR (loop, condExpr),
1592 AST_FOR (loop, loopExpr),
1593 loopCntrl, init, end))
1596 /* now do some serious checking on the body of the loop
1599 return isConformingBody (loop->left, *loopCntrl, loop->left);
1603 /*-----------------------------------------------------------------*/
1604 /* replLoopSym - replace the loop sym by loop sym -1 */
1605 /*-----------------------------------------------------------------*/
1607 replLoopSym (ast * body, symbol * sym)
1610 if (!body || IS_AST_LINK (body))
1613 if (IS_AST_SYM_VALUE (body))
1616 if (isSymbolEqual (AST_SYMBOL (body), sym))
1620 body->opval.op = '-';
1621 body->left = newAst_VALUE (symbolVal (sym));
1622 body->right = newAst_VALUE (constVal ("1"));
1630 replLoopSym (body->left, sym);
1631 replLoopSym (body->right, sym);
1635 /*-----------------------------------------------------------------*/
1636 /* reverseLoop - do the actual loop reversal */
1637 /*-----------------------------------------------------------------*/
1639 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1643 /* create the following tree
1648 if (sym) goto for_continue ;
1651 /* put it together piece by piece */
1652 rloop = newNode (NULLOP,
1653 createIf (newAst_VALUE (symbolVal (sym)),
1655 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1658 newAst_VALUE (symbolVal (sym)),
1661 replLoopSym (loop->left, sym);
1663 rloop = newNode (NULLOP,
1665 newAst_VALUE (symbolVal (sym)),
1666 newNode ('-', end, init)),
1667 createLabel (AST_FOR (loop, continueLabel),
1671 newNode (SUB_ASSIGN,
1672 newAst_VALUE (symbolVal (sym)),
1673 newAst_VALUE (constVal ("1"))),
1676 return decorateType (rloop);
1680 #define DEMAND_INTEGER_PROMOTION
1682 #ifdef DEMAND_INTEGER_PROMOTION
1684 /*-----------------------------------------------------------------*/
1685 /* walk a tree looking for the leaves. Add a typecast to the given */
1686 /* type to each value leaf node. */
1687 /*-----------------------------------------------------------------*/
1689 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1691 if (!node || IS_CALLOP(node))
1693 /* WTF? We should never get here. */
1697 if (!node->left && !node->right)
1699 /* We're at a leaf; if it's a value, apply the typecast */
1700 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1702 *parentPtr = decorateType (newNode (CAST,
1703 newAst_LINK (copyLinkChain (type)),
1711 pushTypeCastToLeaves (type, node->left, &(node->left));
1715 pushTypeCastToLeaves (type, node->right, &(node->right));
1722 /*-----------------------------------------------------------------*/
1723 /* Given an assignment operation in a tree, determine if the LHS */
1724 /* (the result) has a different (integer) type than the RHS. */
1725 /* If so, walk the RHS and add a typecast to the type of the LHS */
1726 /* to all leaf nodes. */
1727 /*-----------------------------------------------------------------*/
1729 propAsgType (ast * tree)
1731 #ifdef DEMAND_INTEGER_PROMOTION
1732 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1734 /* Nothing to do here... */
1738 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1740 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1747 /*-----------------------------------------------------------------*/
1748 /* decorateType - compute type for this tree also does type cheking */
1749 /* this is done bottom up, since type have to flow upwards */
1750 /* it also does constant folding, and paramater checking */
1751 /*-----------------------------------------------------------------*/
1753 decorateType (ast * tree)
1761 /* if already has type then do nothing */
1762 if (tree->decorated)
1765 tree->decorated = 1;
1767 /* print the line */
1768 /* if not block & function */
1769 if (tree->type == EX_OP &&
1770 (tree->opval.op != FUNCTION &&
1771 tree->opval.op != BLOCK &&
1772 tree->opval.op != NULLOP))
1774 filename = tree->filename;
1775 lineno = tree->lineno;
1778 /* if any child is an error | this one is an error do nothing */
1779 if (tree->isError ||
1780 (tree->left && tree->left->isError) ||
1781 (tree->right && tree->right->isError))
1784 /*------------------------------------------------------------------*/
1785 /*----------------------------*/
1786 /* leaf has been reached */
1787 /*----------------------------*/
1788 /* if this is of type value */
1789 /* just get the type */
1790 if (tree->type == EX_VALUE)
1793 if (IS_LITERAL (tree->opval.val->etype))
1796 /* if this is a character array then declare it */
1797 if (IS_ARRAY (tree->opval.val->type))
1798 tree->opval.val = stringToSymbol (tree->opval.val);
1800 /* otherwise just copy the type information */
1801 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1802 if (funcInChain (tree->opval.val->type))
1804 tree->hasVargs = tree->opval.val->sym->hasVargs;
1805 tree->args = copyValueChain (tree->opval.val->sym->args);
1810 if (tree->opval.val->sym)
1812 /* if the undefined flag is set then give error message */
1813 if (tree->opval.val->sym->undefined)
1815 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1817 TTYPE (tree) = TETYPE (tree) =
1818 tree->opval.val->type = tree->opval.val->sym->type =
1819 tree->opval.val->etype = tree->opval.val->sym->etype =
1820 copyLinkChain (INTTYPE);
1825 /* if impilicit i.e. struct/union member then no type */
1826 if (tree->opval.val->sym->implicit)
1827 TTYPE (tree) = TETYPE (tree) = NULL;
1832 /* else copy the type */
1833 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1835 /* and mark it as referenced */
1836 tree->opval.val->sym->isref = 1;
1837 /* if this is of type function or function pointer */
1838 if (funcInChain (tree->opval.val->type))
1840 tree->hasVargs = tree->opval.val->sym->hasVargs;
1841 tree->args = copyValueChain (tree->opval.val->sym->args);
1851 /* if type link for the case of cast */
1852 if (tree->type == EX_LINK)
1854 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1861 dtl = decorateType (tree->left);
1862 dtr = decorateType (tree->right);
1864 /* this is to take care of situations
1865 when the tree gets rewritten */
1866 if (dtl != tree->left)
1868 if (dtr != tree->right)
1872 /* depending on type of operator do */
1874 switch (tree->opval.op)
1876 /*------------------------------------------------------------------*/
1877 /*----------------------------*/
1879 /*----------------------------*/
1882 /* determine which is the array & which the index */
1883 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1886 ast *tempTree = tree->left;
1887 tree->left = tree->right;
1888 tree->right = tempTree;
1891 /* first check if this is a array or a pointer */
1892 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1894 werror (E_NEED_ARRAY_PTR, "[]");
1895 goto errorTreeReturn;
1898 /* check if the type of the idx */
1899 if (!IS_INTEGRAL (RTYPE (tree)))
1901 werror (E_IDX_NOT_INT);
1902 goto errorTreeReturn;
1905 /* if the left is an rvalue then error */
1908 werror (E_LVALUE_REQUIRED, "array access");
1909 goto errorTreeReturn;
1912 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1913 if (IS_PTR(LTYPE(tree))) {
1914 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1918 /*------------------------------------------------------------------*/
1919 /*----------------------------*/
1921 /*----------------------------*/
1923 /* if this is not a structure */
1924 if (!IS_STRUCT (LTYPE (tree)))
1926 werror (E_STRUCT_UNION, ".");
1927 goto errorTreeReturn;
1929 TTYPE (tree) = structElemType (LTYPE (tree),
1930 (tree->right->type == EX_VALUE ?
1931 tree->right->opval.val : NULL), &tree->args);
1932 TETYPE (tree) = getSpec (TTYPE (tree));
1935 /*------------------------------------------------------------------*/
1936 /*----------------------------*/
1937 /* struct/union pointer */
1938 /*----------------------------*/
1940 /* if not pointer to a structure */
1941 if (!IS_PTR (LTYPE (tree)))
1943 werror (E_PTR_REQD);
1944 goto errorTreeReturn;
1947 if (!IS_STRUCT (LTYPE (tree)->next))
1949 werror (E_STRUCT_UNION, "->");
1950 goto errorTreeReturn;
1953 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1954 (tree->right->type == EX_VALUE ?
1955 tree->right->opval.val : NULL), &tree->args);
1956 TETYPE (tree) = getSpec (TTYPE (tree));
1959 /*------------------------------------------------------------------*/
1960 /*----------------------------*/
1961 /* ++/-- operation */
1962 /*----------------------------*/
1963 case INC_OP: /* incerement operator unary so left only */
1966 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1967 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1968 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
1969 werror (E_CODE_WRITE, "++/--");
1978 /*------------------------------------------------------------------*/
1979 /*----------------------------*/
1981 /*----------------------------*/
1982 case '&': /* can be unary */
1983 /* if right is NULL then unary operation */
1984 if (tree->right) /* not an unary operation */
1987 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1989 werror (E_BITWISE_OP);
1990 werror (E_CONTINUE, "left & right types are ");
1991 printTypeChain (LTYPE (tree), stderr);
1992 fprintf (stderr, ",");
1993 printTypeChain (RTYPE (tree), stderr);
1994 fprintf (stderr, "\n");
1995 goto errorTreeReturn;
1998 /* if they are both literal */
1999 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2001 tree->type = EX_VALUE;
2002 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2003 valFromType (RETYPE (tree)), '&');
2005 tree->right = tree->left = NULL;
2006 TETYPE (tree) = tree->opval.val->etype;
2007 TTYPE (tree) = tree->opval.val->type;
2011 /* see if this is a GETHBIT operation if yes
2014 ast *otree = optimizeGetHbit (tree);
2017 return decorateType (otree);
2020 /* if right or left is literal then result of that type */
2021 if (IS_LITERAL (RTYPE (tree)))
2024 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2025 TETYPE (tree) = getSpec (TTYPE (tree));
2026 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2030 if (IS_LITERAL (LTYPE (tree)))
2032 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2033 TETYPE (tree) = getSpec (TTYPE (tree));
2034 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2040 computeType (LTYPE (tree), RTYPE (tree));
2041 TETYPE (tree) = getSpec (TTYPE (tree));
2044 LRVAL (tree) = RRVAL (tree) = 1;
2048 /*------------------------------------------------------------------*/
2049 /*----------------------------*/
2051 /*----------------------------*/
2053 p->class = DECLARATOR;
2054 /* if bit field then error */
2055 if (IS_BITVAR (tree->left->etype))
2057 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2058 goto errorTreeReturn;
2061 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2063 werror (E_ILLEGAL_ADDR, "address of register variable");
2064 goto errorTreeReturn;
2067 if (IS_FUNC (LTYPE (tree)))
2069 werror (E_ILLEGAL_ADDR, "address of function");
2070 goto errorTreeReturn;
2075 werror (E_LVALUE_REQUIRED, "address of");
2076 goto errorTreeReturn;
2078 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2080 DCL_TYPE (p) = CPOINTER;
2081 DCL_PTR_CONST (p) = port->mem.code_ro;
2083 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2084 DCL_TYPE (p) = FPOINTER;
2085 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2086 DCL_TYPE (p) = PPOINTER;
2087 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2088 DCL_TYPE (p) = IPOINTER;
2089 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2090 DCL_TYPE (p) = EEPPOINTER;
2092 DCL_TYPE (p) = POINTER;
2094 if (IS_AST_SYM_VALUE (tree->left))
2096 AST_SYMBOL (tree->left)->addrtaken = 1;
2097 AST_SYMBOL (tree->left)->allocreq = 1;
2100 p->next = LTYPE (tree);
2102 TETYPE (tree) = getSpec (TTYPE (tree));
2103 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2104 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2109 /*------------------------------------------------------------------*/
2110 /*----------------------------*/
2112 /*----------------------------*/
2114 /* if the rewrite succeeds then don't go any furthur */
2116 ast *wtree = optimizeRRCRLC (tree);
2118 return decorateType (wtree);
2120 /*------------------------------------------------------------------*/
2121 /*----------------------------*/
2123 /*----------------------------*/
2125 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2127 werror (E_BITWISE_OP);
2128 werror (E_CONTINUE, "left & right types are ");
2129 printTypeChain (LTYPE (tree), stderr);
2130 fprintf (stderr, ",");
2131 printTypeChain (RTYPE (tree), stderr);
2132 fprintf (stderr, "\n");
2133 goto errorTreeReturn;
2136 /* if they are both literal then */
2137 /* rewrite the tree */
2138 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2140 tree->type = EX_VALUE;
2141 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2142 valFromType (RETYPE (tree)),
2144 tree->right = tree->left = NULL;
2145 TETYPE (tree) = tree->opval.val->etype;
2146 TTYPE (tree) = tree->opval.val->type;
2149 LRVAL (tree) = RRVAL (tree) = 1;
2150 TETYPE (tree) = getSpec (TTYPE (tree) =
2151 computeType (LTYPE (tree),
2154 /*------------------------------------------------------------------*/
2155 /*----------------------------*/
2157 /*----------------------------*/
2159 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2161 werror (E_INVALID_OP, "divide");
2162 goto errorTreeReturn;
2164 /* if they are both literal then */
2165 /* rewrite the tree */
2166 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2168 tree->type = EX_VALUE;
2169 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2170 valFromType (RETYPE (tree)));
2171 tree->right = tree->left = NULL;
2172 TETYPE (tree) = getSpec (TTYPE (tree) =
2173 tree->opval.val->type);
2176 LRVAL (tree) = RRVAL (tree) = 1;
2177 TETYPE (tree) = getSpec (TTYPE (tree) =
2178 computeType (LTYPE (tree),
2182 /*------------------------------------------------------------------*/
2183 /*----------------------------*/
2185 /*----------------------------*/
2187 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2189 werror (E_BITWISE_OP);
2190 werror (E_CONTINUE, "left & right types are ");
2191 printTypeChain (LTYPE (tree), stderr);
2192 fprintf (stderr, ",");
2193 printTypeChain (RTYPE (tree), stderr);
2194 fprintf (stderr, "\n");
2195 goto errorTreeReturn;
2197 /* if they are both literal then */
2198 /* rewrite the tree */
2199 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2201 tree->type = EX_VALUE;
2202 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2203 valFromType (RETYPE (tree)));
2204 tree->right = tree->left = NULL;
2205 TETYPE (tree) = getSpec (TTYPE (tree) =
2206 tree->opval.val->type);
2209 LRVAL (tree) = RRVAL (tree) = 1;
2210 TETYPE (tree) = getSpec (TTYPE (tree) =
2211 computeType (LTYPE (tree),
2215 /*------------------------------------------------------------------*/
2216 /*----------------------------*/
2217 /* address dereference */
2218 /*----------------------------*/
2219 case '*': /* can be unary : if right is null then unary operation */
2222 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2224 werror (E_PTR_REQD);
2225 goto errorTreeReturn;
2230 werror (E_LVALUE_REQUIRED, "pointer deref");
2231 goto errorTreeReturn;
2233 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2234 LTYPE (tree)->next : NULL);
2235 TETYPE (tree) = getSpec (TTYPE (tree));
2236 tree->args = tree->left->args;
2237 tree->hasVargs = tree->left->hasVargs;
2238 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2242 /*------------------------------------------------------------------*/
2243 /*----------------------------*/
2244 /* multiplication */
2245 /*----------------------------*/
2246 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2248 werror (E_INVALID_OP, "multiplication");
2249 goto errorTreeReturn;
2252 /* if they are both literal then */
2253 /* rewrite the tree */
2254 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2256 tree->type = EX_VALUE;
2257 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2258 valFromType (RETYPE (tree)));
2259 tree->right = tree->left = NULL;
2260 TETYPE (tree) = getSpec (TTYPE (tree) =
2261 tree->opval.val->type);
2265 /* if left is a literal exchange left & right */
2266 if (IS_LITERAL (LTYPE (tree)))
2268 ast *tTree = tree->left;
2269 tree->left = tree->right;
2270 tree->right = tTree;
2273 LRVAL (tree) = RRVAL (tree) = 1;
2274 /* promote result to int if left & right are char / short
2275 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2276 if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) &&
2277 (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
2278 TETYPE (tree) = getSpec (TTYPE (tree) =
2279 computeType (LTYPE (tree),
2281 SPEC_NOUN(TETYPE(tree)) = V_INT;
2282 SPEC_SHORT(TETYPE(tree))=0;
2284 TETYPE (tree) = getSpec (TTYPE (tree) =
2285 computeType (LTYPE (tree),
2290 /*------------------------------------------------------------------*/
2291 /*----------------------------*/
2292 /* unary '+' operator */
2293 /*----------------------------*/
2298 if (!IS_INTEGRAL (LTYPE (tree)))
2300 werror (E_UNARY_OP, '+');
2301 goto errorTreeReturn;
2304 /* if left is a literal then do it */
2305 if (IS_LITERAL (LTYPE (tree)))
2307 tree->type = EX_VALUE;
2308 tree->opval.val = valFromType (LETYPE (tree));
2310 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2314 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2318 /*------------------------------------------------------------------*/
2319 /*----------------------------*/
2321 /*----------------------------*/
2323 /* this is not a unary operation */
2324 /* if both pointers then problem */
2325 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2326 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2328 werror (E_PTR_PLUS_PTR);
2329 goto errorTreeReturn;
2332 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2333 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2335 werror (E_PLUS_INVALID, "+");
2336 goto errorTreeReturn;
2339 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2340 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2342 werror (E_PLUS_INVALID, "+");
2343 goto errorTreeReturn;
2345 /* if they are both literal then */
2346 /* rewrite the tree */
2347 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2349 tree->type = EX_VALUE;
2350 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2351 valFromType (RETYPE (tree)));
2352 tree->right = tree->left = NULL;
2353 TETYPE (tree) = getSpec (TTYPE (tree) =
2354 tree->opval.val->type);
2358 /* if the right is a pointer or left is a literal
2359 xchange left & right */
2360 if (IS_ARRAY (RTYPE (tree)) ||
2361 IS_PTR (RTYPE (tree)) ||
2362 IS_LITERAL (LTYPE (tree)))
2364 ast *tTree = tree->left;
2365 tree->left = tree->right;
2366 tree->right = tTree;
2369 LRVAL (tree) = RRVAL (tree) = 1;
2370 /* if the left is a pointer */
2371 if (IS_PTR (LTYPE (tree)))
2372 TETYPE (tree) = getSpec (TTYPE (tree) =
2375 TETYPE (tree) = getSpec (TTYPE (tree) =
2376 computeType (LTYPE (tree),
2380 /*------------------------------------------------------------------*/
2381 /*----------------------------*/
2383 /*----------------------------*/
2384 case '-': /* can be unary */
2385 /* if right is null then unary */
2389 if (!IS_ARITHMETIC (LTYPE (tree)))
2391 werror (E_UNARY_OP, tree->opval.op);
2392 goto errorTreeReturn;
2395 /* if left is a literal then do it */
2396 if (IS_LITERAL (LTYPE (tree)))
2398 tree->type = EX_VALUE;
2399 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2401 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2402 SPEC_USIGN(TETYPE(tree)) = 0;
2406 TTYPE (tree) = LTYPE (tree);
2410 /*------------------------------------------------------------------*/
2411 /*----------------------------*/
2413 /*----------------------------*/
2415 if (!(IS_PTR (LTYPE (tree)) ||
2416 IS_ARRAY (LTYPE (tree)) ||
2417 IS_ARITHMETIC (LTYPE (tree))))
2419 werror (E_PLUS_INVALID, "-");
2420 goto errorTreeReturn;
2423 if (!(IS_PTR (RTYPE (tree)) ||
2424 IS_ARRAY (RTYPE (tree)) ||
2425 IS_ARITHMETIC (RTYPE (tree))))
2427 werror (E_PLUS_INVALID, "-");
2428 goto errorTreeReturn;
2431 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2432 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2433 IS_INTEGRAL (RTYPE (tree))))
2435 werror (E_PLUS_INVALID, "-");
2436 goto errorTreeReturn;
2439 /* if they are both literal then */
2440 /* rewrite the tree */
2441 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2443 tree->type = EX_VALUE;
2444 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2445 valFromType (RETYPE (tree)));
2446 tree->right = tree->left = NULL;
2447 TETYPE (tree) = getSpec (TTYPE (tree) =
2448 tree->opval.val->type);
2452 /* if the left & right are equal then zero */
2453 if (isAstEqual (tree->left, tree->right))
2455 tree->type = EX_VALUE;
2456 tree->left = tree->right = NULL;
2457 tree->opval.val = constVal ("0");
2458 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2462 /* if both of them are pointers or arrays then */
2463 /* the result is going to be an integer */
2464 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2465 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2466 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2468 /* if only the left is a pointer */
2469 /* then result is a pointer */
2470 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2471 TETYPE (tree) = getSpec (TTYPE (tree) =
2474 TETYPE (tree) = getSpec (TTYPE (tree) =
2475 computeType (LTYPE (tree),
2477 LRVAL (tree) = RRVAL (tree) = 1;
2480 /*------------------------------------------------------------------*/
2481 /*----------------------------*/
2483 /*----------------------------*/
2485 /* can be only integral type */
2486 if (!IS_INTEGRAL (LTYPE (tree)))
2488 werror (E_UNARY_OP, tree->opval.op);
2489 goto errorTreeReturn;
2492 /* if left is a literal then do it */
2493 if (IS_LITERAL (LTYPE (tree)))
2495 tree->type = EX_VALUE;
2496 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2498 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2502 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2505 /*------------------------------------------------------------------*/
2506 /*----------------------------*/
2508 /*----------------------------*/
2510 /* can be pointer */
2511 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2512 !IS_PTR (LTYPE (tree)) &&
2513 !IS_ARRAY (LTYPE (tree)))
2515 werror (E_UNARY_OP, tree->opval.op);
2516 goto errorTreeReturn;
2519 /* if left is a literal then do it */
2520 if (IS_LITERAL (LTYPE (tree)))
2522 tree->type = EX_VALUE;
2523 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2525 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2529 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2532 /*------------------------------------------------------------------*/
2533 /*----------------------------*/
2535 /*----------------------------*/
2538 TTYPE (tree) = LTYPE (tree);
2539 TETYPE (tree) = LETYPE (tree);
2543 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2548 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2550 werror (E_SHIFT_OP_INVALID);
2551 werror (E_CONTINUE, "left & right types are ");
2552 printTypeChain (LTYPE (tree), stderr);
2553 fprintf (stderr, ",");
2554 printTypeChain (RTYPE (tree), stderr);
2555 fprintf (stderr, "\n");
2556 goto errorTreeReturn;
2559 /* if they are both literal then */
2560 /* rewrite the tree */
2561 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2563 tree->type = EX_VALUE;
2564 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2565 valFromType (RETYPE (tree)),
2566 (tree->opval.op == LEFT_OP ? 1 : 0));
2567 tree->right = tree->left = NULL;
2568 TETYPE (tree) = getSpec (TTYPE (tree) =
2569 tree->opval.val->type);
2572 /* if only the right side is a literal & we are
2573 shifting more than size of the left operand then zero */
2574 if (IS_LITERAL (RTYPE (tree)) &&
2575 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2576 (getSize (LTYPE (tree)) * 8))
2578 werror (W_SHIFT_CHANGED,
2579 (tree->opval.op == LEFT_OP ? "left" : "right"));
2580 tree->type = EX_VALUE;
2581 tree->left = tree->right = NULL;
2582 tree->opval.val = constVal ("0");
2583 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2586 LRVAL (tree) = RRVAL (tree) = 1;
2587 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2589 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2593 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2597 /*------------------------------------------------------------------*/
2598 /*----------------------------*/
2600 /*----------------------------*/
2601 case CAST: /* change the type */
2602 /* cannot cast to an aggregate type */
2603 if (IS_AGGREGATE (LTYPE (tree)))
2605 werror (E_CAST_ILLEGAL);
2606 goto errorTreeReturn;
2609 /* if the right is a literal replace the tree */
2610 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2612 tree->type = EX_VALUE;
2614 valCastLiteral (LTYPE (tree),
2615 floatFromVal (valFromType (RETYPE (tree))));
2618 TTYPE (tree) = tree->opval.val->type;
2619 tree->values.literalFromCast = 1;
2623 TTYPE (tree) = LTYPE (tree);
2627 TETYPE (tree) = getSpec (TTYPE (tree));
2631 /*------------------------------------------------------------------*/
2632 /*----------------------------*/
2633 /* logical &&, || */
2634 /*----------------------------*/
2637 /* each must me arithmetic type or be a pointer */
2638 if (!IS_PTR (LTYPE (tree)) &&
2639 !IS_ARRAY (LTYPE (tree)) &&
2640 !IS_INTEGRAL (LTYPE (tree)))
2642 werror (E_COMPARE_OP);
2643 goto errorTreeReturn;
2646 if (!IS_PTR (RTYPE (tree)) &&
2647 !IS_ARRAY (RTYPE (tree)) &&
2648 !IS_INTEGRAL (RTYPE (tree)))
2650 werror (E_COMPARE_OP);
2651 goto errorTreeReturn;
2653 /* if they are both literal then */
2654 /* rewrite the tree */
2655 if (IS_LITERAL (RTYPE (tree)) &&
2656 IS_LITERAL (LTYPE (tree)))
2658 tree->type = EX_VALUE;
2659 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2660 valFromType (RETYPE (tree)),
2662 tree->right = tree->left = NULL;
2663 TETYPE (tree) = getSpec (TTYPE (tree) =
2664 tree->opval.val->type);
2667 LRVAL (tree) = RRVAL (tree) = 1;
2668 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2671 /*------------------------------------------------------------------*/
2672 /*----------------------------*/
2673 /* comparison operators */
2674 /*----------------------------*/
2682 ast *lt = optimizeCompare (tree);
2688 /* if they are pointers they must be castable */
2689 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2691 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2693 werror (E_COMPARE_OP);
2694 fprintf (stderr, "comparing type ");
2695 printTypeChain (LTYPE (tree), stderr);
2696 fprintf (stderr, "to type ");
2697 printTypeChain (RTYPE (tree), stderr);
2698 fprintf (stderr, "\n");
2699 goto errorTreeReturn;
2702 /* else they should be promotable to one another */
2705 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2706 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2708 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2710 werror (E_COMPARE_OP);
2711 fprintf (stderr, "comparing type ");
2712 printTypeChain (LTYPE (tree), stderr);
2713 fprintf (stderr, "to type ");
2714 printTypeChain (RTYPE (tree), stderr);
2715 fprintf (stderr, "\n");
2716 goto errorTreeReturn;
2720 /* if they are both literal then */
2721 /* rewrite the tree */
2722 if (IS_LITERAL (RTYPE (tree)) &&
2723 IS_LITERAL (LTYPE (tree)))
2725 tree->type = EX_VALUE;
2726 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2727 valFromType (RETYPE (tree)),
2729 tree->right = tree->left = NULL;
2730 TETYPE (tree) = getSpec (TTYPE (tree) =
2731 tree->opval.val->type);
2734 LRVAL (tree) = RRVAL (tree) = 1;
2735 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2738 /*------------------------------------------------------------------*/
2739 /*----------------------------*/
2741 /*----------------------------*/
2742 case SIZEOF: /* evaluate wihout code generation */
2743 /* change the type to a integer */
2744 tree->type = EX_VALUE;
2745 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2746 tree->opval.val = constVal (buffer);
2747 tree->right = tree->left = NULL;
2748 TETYPE (tree) = getSpec (TTYPE (tree) =
2749 tree->opval.val->type);
2752 /*------------------------------------------------------------------*/
2753 /*----------------------------*/
2754 /* conditional operator '?' */
2755 /*----------------------------*/
2757 /* the type is one on the left */
2758 TTYPE (tree) = LTYPE (tree);
2759 TETYPE (tree) = getSpec (TTYPE (tree));
2763 /* if they don't match we have a problem */
2764 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2766 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2767 goto errorTreeReturn;
2770 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2771 TETYPE (tree) = getSpec (TTYPE (tree));
2775 /*------------------------------------------------------------------*/
2776 /*----------------------------*/
2777 /* assignment operators */
2778 /*----------------------------*/
2781 /* for these it must be both must be integral */
2782 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2783 !IS_ARITHMETIC (RTYPE (tree)))
2785 werror (E_OPS_INTEGRAL);
2786 goto errorTreeReturn;
2789 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2791 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2792 werror (E_CODE_WRITE, " ");
2796 werror (E_LVALUE_REQUIRED, "*= or /=");
2797 goto errorTreeReturn;
2810 /* for these it must be both must be integral */
2811 if (!IS_INTEGRAL (LTYPE (tree)) ||
2812 !IS_INTEGRAL (RTYPE (tree)))
2814 werror (E_OPS_INTEGRAL);
2815 goto errorTreeReturn;
2818 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2820 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2821 werror (E_CODE_WRITE, " ");
2825 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2826 goto errorTreeReturn;
2834 /*------------------------------------------------------------------*/
2835 /*----------------------------*/
2837 /*----------------------------*/
2839 if (!(IS_PTR (LTYPE (tree)) ||
2840 IS_ARITHMETIC (LTYPE (tree))))
2842 werror (E_PLUS_INVALID, "-=");
2843 goto errorTreeReturn;
2846 if (!(IS_PTR (RTYPE (tree)) ||
2847 IS_ARITHMETIC (RTYPE (tree))))
2849 werror (E_PLUS_INVALID, "-=");
2850 goto errorTreeReturn;
2853 TETYPE (tree) = getSpec (TTYPE (tree) =
2854 computeType (LTYPE (tree),
2857 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2858 werror (E_CODE_WRITE, " ");
2862 werror (E_LVALUE_REQUIRED, "-=");
2863 goto errorTreeReturn;
2871 /*------------------------------------------------------------------*/
2872 /*----------------------------*/
2874 /*----------------------------*/
2876 /* this is not a unary operation */
2877 /* if both pointers then problem */
2878 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2880 werror (E_PTR_PLUS_PTR);
2881 goto errorTreeReturn;
2884 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2886 werror (E_PLUS_INVALID, "+=");
2887 goto errorTreeReturn;
2890 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2892 werror (E_PLUS_INVALID, "+=");
2893 goto errorTreeReturn;
2896 TETYPE (tree) = getSpec (TTYPE (tree) =
2897 computeType (LTYPE (tree),
2900 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2901 werror (E_CODE_WRITE, " ");
2905 werror (E_LVALUE_REQUIRED, "+=");
2906 goto errorTreeReturn;
2909 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2910 tree->opval.op = '=';
2916 /*------------------------------------------------------------------*/
2917 /*----------------------------*/
2918 /* straight assignemnt */
2919 /*----------------------------*/
2921 /* cannot be an aggregate */
2922 if (IS_AGGREGATE (LTYPE (tree)))
2924 werror (E_AGGR_ASSIGN);
2925 goto errorTreeReturn;
2928 /* they should either match or be castable */
2929 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2931 werror (E_TYPE_MISMATCH, "assignment", " ");
2932 fprintf (stderr, "type --> '");
2933 printTypeChain (RTYPE (tree), stderr);
2934 fprintf (stderr, "' ");
2935 fprintf (stderr, "assigned to type --> '");
2936 printTypeChain (LTYPE (tree), stderr);
2937 fprintf (stderr, "'\n");
2938 goto errorTreeReturn;
2941 /* if the left side of the tree is of type void
2942 then report error */
2943 if (IS_VOID (LTYPE (tree)))
2945 werror (E_CAST_ZERO);
2946 fprintf (stderr, "type --> '");
2947 printTypeChain (RTYPE (tree), stderr);
2948 fprintf (stderr, "' ");
2949 fprintf (stderr, "assigned to type --> '");
2950 printTypeChain (LTYPE (tree), stderr);
2951 fprintf (stderr, "'\n");
2954 /* extra checks for pointer types */
2955 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2956 !IS_GENPTR (LTYPE (tree)))
2958 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2959 werror (W_PTR_ASSIGN);
2962 TETYPE (tree) = getSpec (TTYPE (tree) =
2966 if (!tree->initMode ) {
2967 if (IS_CONSTANT (LETYPE (tree))) {
2968 werror (E_CODE_WRITE, " ");
2973 werror (E_LVALUE_REQUIRED, "=");
2974 goto errorTreeReturn;
2981 /*------------------------------------------------------------------*/
2982 /*----------------------------*/
2983 /* comma operator */
2984 /*----------------------------*/
2986 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
2989 /*------------------------------------------------------------------*/
2990 /*----------------------------*/
2992 /*----------------------------*/
2996 if (processParms (tree->left,
2998 tree->right, &parmNumber, TRUE))
2999 goto errorTreeReturn;
3001 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3003 tree->left->args = reverseVal (tree->left->args);
3004 reverseParms (tree->right);
3007 tree->args = tree->left->args;
3008 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3011 /*------------------------------------------------------------------*/
3012 /*----------------------------*/
3013 /* return statement */
3014 /*----------------------------*/
3019 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3021 werror (E_RETURN_MISMATCH);
3022 goto errorTreeReturn;
3025 if (IS_VOID (currFunc->type->next)
3027 !IS_VOID (RTYPE (tree)))
3029 werror (E_FUNC_VOID);
3030 goto errorTreeReturn;
3033 /* if there is going to be a casing required then add it */
3034 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3036 #if 0 && defined DEMAND_INTEGER_PROMOTION
3037 if (IS_INTEGRAL (currFunc->type->next))
3039 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3045 decorateType (newNode (CAST,
3046 newAst_LINK (copyLinkChain (currFunc->type->next)),
3056 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3058 werror (E_VOID_FUNC, currFunc->name);
3059 goto errorTreeReturn;
3062 TTYPE (tree) = TETYPE (tree) = NULL;
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3067 /* switch statement */
3068 /*----------------------------*/
3070 /* the switch value must be an integer */
3071 if (!IS_INTEGRAL (LTYPE (tree)))
3073 werror (E_SWITCH_NON_INTEGER);
3074 goto errorTreeReturn;
3077 TTYPE (tree) = TETYPE (tree) = NULL;
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3083 /*----------------------------*/
3085 tree->left = backPatchLabels (tree->left,
3088 TTYPE (tree) = TETYPE (tree) = NULL;
3091 /*------------------------------------------------------------------*/
3092 /*----------------------------*/
3094 /*----------------------------*/
3097 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3098 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3099 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3101 /* if the for loop is reversible then
3102 reverse it otherwise do what we normally
3108 if (isLoopReversible (tree, &sym, &init, &end))
3109 return reverseLoop (tree, sym, init, end);
3111 return decorateType (createFor (AST_FOR (tree, trueLabel),
3112 AST_FOR (tree, continueLabel),
3113 AST_FOR (tree, falseLabel),
3114 AST_FOR (tree, condLabel),
3115 AST_FOR (tree, initExpr),
3116 AST_FOR (tree, condExpr),
3117 AST_FOR (tree, loopExpr),
3121 TTYPE (tree) = TETYPE (tree) = NULL;
3125 /* some error found this tree will be killed */
3127 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3128 tree->opval.op = NULLOP;
3134 /*-----------------------------------------------------------------*/
3135 /* sizeofOp - processes size of operation */
3136 /*-----------------------------------------------------------------*/
3138 sizeofOp (sym_link * type)
3142 /* get the size and convert it to character */
3143 sprintf (buff, "%d", getSize (type));
3145 /* now convert into value */
3146 return constVal (buff);
3150 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3151 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3152 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3153 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3154 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3155 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3156 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3158 /*-----------------------------------------------------------------*/
3159 /* backPatchLabels - change and or not operators to flow control */
3160 /*-----------------------------------------------------------------*/
3162 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3168 if (!(IS_ANDORNOT (tree)))
3171 /* if this an and */
3174 static int localLbl = 0;
3177 sprintf (buffer, "_and_%d", localLbl++);
3178 localLabel = newSymbol (buffer, NestLevel);
3180 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3182 /* if left is already a IFX then just change the if true label in that */
3183 if (!IS_IFX (tree->left))
3184 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3186 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3187 /* right is a IFX then just join */
3188 if (IS_IFX (tree->right))
3189 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3191 tree->right = createLabel (localLabel, tree->right);
3192 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3194 return newNode (NULLOP, tree->left, tree->right);
3197 /* if this is an or operation */
3200 static int localLbl = 0;
3203 sprintf (buffer, "_or_%d", localLbl++);
3204 localLabel = newSymbol (buffer, NestLevel);
3206 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3208 /* if left is already a IFX then just change the if true label in that */
3209 if (!IS_IFX (tree->left))
3210 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3212 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3213 /* right is a IFX then just join */
3214 if (IS_IFX (tree->right))
3215 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3217 tree->right = createLabel (localLabel, tree->right);
3218 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3220 return newNode (NULLOP, tree->left, tree->right);
3226 int wasnot = IS_NOT (tree->left);
3227 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3229 /* if the left is already a IFX */
3230 if (!IS_IFX (tree->left))
3231 tree->left = newNode (IFX, tree->left, NULL);
3235 tree->left->trueLabel = trueLabel;
3236 tree->left->falseLabel = falseLabel;
3240 tree->left->trueLabel = falseLabel;
3241 tree->left->falseLabel = trueLabel;
3248 tree->trueLabel = trueLabel;
3249 tree->falseLabel = falseLabel;
3256 /*-----------------------------------------------------------------*/
3257 /* createBlock - create expression tree for block */
3258 /*-----------------------------------------------------------------*/
3260 createBlock (symbol * decl, ast * body)
3264 /* if the block has nothing */
3268 ex = newNode (BLOCK, NULL, body);
3269 ex->values.sym = decl;
3271 ex->right = ex->right;
3277 /*-----------------------------------------------------------------*/
3278 /* createLabel - creates the expression tree for labels */
3279 /*-----------------------------------------------------------------*/
3281 createLabel (symbol * label, ast * stmnt)
3284 char name[SDCC_NAME_MAX + 1];
3287 /* must create fresh symbol if the symbol name */
3288 /* exists in the symbol table, since there can */
3289 /* be a variable with the same name as the labl */
3290 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3291 (csym->level == label->level))
3292 label = newSymbol (label->name, label->level);
3294 /* change the name before putting it in add _ */
3295 sprintf (name, "%s", label->name);
3297 /* put the label in the LabelSymbol table */
3298 /* but first check if a label of the same */
3300 if ((csym = findSym (LabelTab, NULL, name)))
3301 werror (E_DUPLICATE_LABEL, label->name);
3303 addSym (LabelTab, label, name, label->level, 0);
3306 label->key = labelKey++;
3307 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3313 /*-----------------------------------------------------------------*/
3314 /* createCase - generates the parsetree for a case statement */
3315 /*-----------------------------------------------------------------*/
3317 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3319 char caseLbl[SDCC_NAME_MAX + 1];
3323 /* if the switch statement does not exist */
3324 /* then case is out of context */
3327 werror (E_CASE_CONTEXT);
3331 caseVal = decorateType (resolveSymbols (caseVal));
3332 /* if not a constant then error */
3333 if (!IS_LITERAL (caseVal->ftype))
3335 werror (E_CASE_CONSTANT);
3339 /* if not a integer than error */
3340 if (!IS_INTEGRAL (caseVal->ftype))
3342 werror (E_CASE_NON_INTEGER);
3346 /* find the end of the switch values chain */
3347 if (!(val = swStat->values.switchVals.swVals))
3348 swStat->values.switchVals.swVals = caseVal->opval.val;
3351 /* also order the cases according to value */
3353 int cVal = (int) floatFromVal (caseVal->opval.val);
3354 while (val && (int) floatFromVal (val) < cVal)
3360 /* if we reached the end then */
3363 pval->next = caseVal->opval.val;
3367 /* we found a value greater than */
3368 /* the current value we must add this */
3369 /* before the value */
3370 caseVal->opval.val->next = val;
3372 /* if this was the first in chain */
3373 if (swStat->values.switchVals.swVals == val)
3374 swStat->values.switchVals.swVals =
3377 pval->next = caseVal->opval.val;
3382 /* create the case label */
3383 sprintf (caseLbl, "_case_%d_%d",
3384 swStat->values.switchVals.swNum,
3385 (int) floatFromVal (caseVal->opval.val));
3387 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3392 /*-----------------------------------------------------------------*/
3393 /* createDefault - creates the parse tree for the default statement */
3394 /*-----------------------------------------------------------------*/
3396 createDefault (ast * swStat, ast * stmnt)
3398 char defLbl[SDCC_NAME_MAX + 1];
3400 /* if the switch statement does not exist */
3401 /* then case is out of context */
3404 werror (E_CASE_CONTEXT);
3408 /* turn on the default flag */
3409 swStat->values.switchVals.swDefault = 1;
3411 /* create the label */
3412 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3413 return createLabel (newSymbol (defLbl, 0), stmnt);
3416 /*-----------------------------------------------------------------*/
3417 /* createIf - creates the parsetree for the if statement */
3418 /*-----------------------------------------------------------------*/
3420 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3422 static int Lblnum = 0;
3424 symbol *ifTrue, *ifFalse, *ifEnd;
3426 /* if neither exists */
3427 if (!elseBody && !ifBody)
3430 /* create the labels */
3431 sprintf (buffer, "_iffalse_%d", Lblnum);
3432 ifFalse = newSymbol (buffer, NestLevel);
3433 /* if no else body then end == false */
3438 sprintf (buffer, "_ifend_%d", Lblnum);
3439 ifEnd = newSymbol (buffer, NestLevel);
3442 sprintf (buffer, "_iftrue_%d", Lblnum);
3443 ifTrue = newSymbol (buffer, NestLevel);
3447 /* attach the ifTrue label to the top of it body */
3448 ifBody = createLabel (ifTrue, ifBody);
3449 /* attach a goto end to the ifBody if else is present */
3452 ifBody = newNode (NULLOP, ifBody,
3454 newAst_VALUE (symbolVal (ifEnd)),
3456 /* put the elseLabel on the else body */
3457 elseBody = createLabel (ifFalse, elseBody);
3458 /* out the end at the end of the body */
3459 elseBody = newNode (NULLOP,
3461 createLabel (ifEnd, NULL));
3465 ifBody = newNode (NULLOP, ifBody,
3466 createLabel (ifFalse, NULL));
3468 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3469 if (IS_IFX (condAst))
3472 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3474 return newNode (NULLOP, ifTree,
3475 newNode (NULLOP, ifBody, elseBody));
3479 /*-----------------------------------------------------------------*/
3480 /* createDo - creates parse tree for do */
3483 /* _docontinue_n: */
3484 /* condition_expression +-> trueLabel -> _dobody_n */
3486 /* +-> falseLabel-> _dobreak_n */
3488 /*-----------------------------------------------------------------*/
3490 createDo (symbol * trueLabel, symbol * continueLabel,
3491 symbol * falseLabel, ast * condAst, ast * doBody)
3496 /* if the body does not exist then it is simple */
3499 condAst = backPatchLabels (condAst, continueLabel, NULL);
3500 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3501 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3502 doTree->trueLabel = continueLabel;
3503 doTree->falseLabel = NULL;
3507 /* otherwise we have a body */
3508 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3510 /* attach the body label to the top */
3511 doBody = createLabel (trueLabel, doBody);
3512 /* attach the continue label to end of body */
3513 doBody = newNode (NULLOP, doBody,
3514 createLabel (continueLabel, NULL));
3516 /* now put the break label at the end */
3517 if (IS_IFX (condAst))
3520 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3522 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3524 /* putting it together */
3525 return newNode (NULLOP, doBody, doTree);
3528 /*-----------------------------------------------------------------*/
3529 /* createFor - creates parse tree for 'for' statement */
3532 /* condExpr +-> trueLabel -> _forbody_n */
3534 /* +-> falseLabel-> _forbreak_n */
3537 /* _forcontinue_n: */
3539 /* goto _forcond_n ; */
3541 /*-----------------------------------------------------------------*/
3543 createFor (symbol * trueLabel, symbol * continueLabel,
3544 symbol * falseLabel, symbol * condLabel,
3545 ast * initExpr, ast * condExpr, ast * loopExpr,
3550 /* if loopexpression not present then we can generate it */
3551 /* the same way as a while */
3553 return newNode (NULLOP, initExpr,
3554 createWhile (trueLabel, continueLabel,
3555 falseLabel, condExpr, forBody));
3556 /* vanilla for statement */
3557 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3559 if (condExpr && !IS_IFX (condExpr))
3560 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3563 /* attach condition label to condition */
3564 condExpr = createLabel (condLabel, condExpr);
3566 /* attach body label to body */
3567 forBody = createLabel (trueLabel, forBody);
3569 /* attach continue to forLoop expression & attach */
3570 /* goto the forcond @ and of loopExpression */
3571 loopExpr = createLabel (continueLabel,
3575 newAst_VALUE (symbolVal (condLabel)),
3577 /* now start putting them together */
3578 forTree = newNode (NULLOP, initExpr, condExpr);
3579 forTree = newNode (NULLOP, forTree, forBody);
3580 forTree = newNode (NULLOP, forTree, loopExpr);
3581 /* finally add the break label */
3582 forTree = newNode (NULLOP, forTree,
3583 createLabel (falseLabel, NULL));
3587 /*-----------------------------------------------------------------*/
3588 /* createWhile - creates parse tree for while statement */
3589 /* the while statement will be created as follows */
3591 /* _while_continue_n: */
3592 /* condition_expression +-> trueLabel -> _while_boby_n */
3594 /* +-> falseLabel -> _while_break_n */
3595 /* _while_body_n: */
3597 /* goto _while_continue_n */
3598 /* _while_break_n: */
3599 /*-----------------------------------------------------------------*/
3601 createWhile (symbol * trueLabel, symbol * continueLabel,
3602 symbol * falseLabel, ast * condExpr, ast * whileBody)
3606 /* put the continue label */
3607 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3608 condExpr = createLabel (continueLabel, condExpr);
3609 condExpr->lineno = 0;
3611 /* put the body label in front of the body */
3612 whileBody = createLabel (trueLabel, whileBody);
3613 whileBody->lineno = 0;
3614 /* put a jump to continue at the end of the body */
3615 /* and put break label at the end of the body */
3616 whileBody = newNode (NULLOP,
3619 newAst_VALUE (symbolVal (continueLabel)),
3620 createLabel (falseLabel, NULL)));
3622 /* put it all together */
3623 if (IS_IFX (condExpr))
3624 whileTree = condExpr;
3627 whileTree = newNode (IFX, condExpr, NULL);
3628 /* put the true & false labels in place */
3629 whileTree->trueLabel = trueLabel;
3630 whileTree->falseLabel = falseLabel;
3633 return newNode (NULLOP, whileTree, whileBody);
3636 /*-----------------------------------------------------------------*/
3637 /* optimizeGetHbit - get highest order bit of the expression */
3638 /*-----------------------------------------------------------------*/
3640 optimizeGetHbit (ast * tree)
3643 /* if this is not a bit and */
3644 if (!IS_BITAND (tree))
3647 /* will look for tree of the form
3648 ( expr >> ((sizeof expr) -1) ) & 1 */
3649 if (!IS_AST_LIT_VALUE (tree->right))
3652 if (AST_LIT_VALUE (tree->right) != 1)
3655 if (!IS_RIGHT_OP (tree->left))
3658 if (!IS_AST_LIT_VALUE (tree->left->right))
3661 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3662 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3665 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3669 /*-----------------------------------------------------------------*/
3670 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3671 /*-----------------------------------------------------------------*/
3673 optimizeRRCRLC (ast * root)
3675 /* will look for trees of the form
3676 (?expr << 1) | (?expr >> 7) or
3677 (?expr >> 7) | (?expr << 1) will make that
3678 into a RLC : operation ..
3680 (?expr >> 1) | (?expr << 7) or
3681 (?expr << 7) | (?expr >> 1) will make that
3682 into a RRC operation
3683 note : by 7 I mean (number of bits required to hold the
3685 /* if the root operations is not a | operation the not */
3686 if (!IS_BITOR (root))
3689 /* I have to think of a better way to match patterns this sucks */
3690 /* that aside let start looking for the first case : I use a the
3691 negative check a lot to improve the efficiency */
3692 /* (?expr << 1) | (?expr >> 7) */
3693 if (IS_LEFT_OP (root->left) &&
3694 IS_RIGHT_OP (root->right))
3697 if (!SPEC_USIGN (TETYPE (root->left->left)))
3700 if (!IS_AST_LIT_VALUE (root->left->right) ||
3701 !IS_AST_LIT_VALUE (root->right->right))
3704 /* make sure it is the same expression */
3705 if (!isAstEqual (root->left->left,
3709 if (AST_LIT_VALUE (root->left->right) != 1)
3712 if (AST_LIT_VALUE (root->right->right) !=
3713 (getSize (TTYPE (root->left->left)) * 8 - 1))
3716 /* whew got the first case : create the AST */
3717 return newNode (RLC, root->left->left, NULL);
3721 /* check for second case */
3722 /* (?expr >> 7) | (?expr << 1) */
3723 if (IS_LEFT_OP (root->right) &&
3724 IS_RIGHT_OP (root->left))
3727 if (!SPEC_USIGN (TETYPE (root->left->left)))
3730 if (!IS_AST_LIT_VALUE (root->left->right) ||
3731 !IS_AST_LIT_VALUE (root->right->right))
3734 /* make sure it is the same symbol */
3735 if (!isAstEqual (root->left->left,
3739 if (AST_LIT_VALUE (root->right->right) != 1)
3742 if (AST_LIT_VALUE (root->left->right) !=
3743 (getSize (TTYPE (root->left->left)) * 8 - 1))
3746 /* whew got the first case : create the AST */
3747 return newNode (RLC, root->left->left, NULL);
3752 /* third case for RRC */
3753 /* (?symbol >> 1) | (?symbol << 7) */
3754 if (IS_LEFT_OP (root->right) &&
3755 IS_RIGHT_OP (root->left))
3758 if (!SPEC_USIGN (TETYPE (root->left->left)))
3761 if (!IS_AST_LIT_VALUE (root->left->right) ||
3762 !IS_AST_LIT_VALUE (root->right->right))
3765 /* make sure it is the same symbol */
3766 if (!isAstEqual (root->left->left,
3770 if (AST_LIT_VALUE (root->left->right) != 1)
3773 if (AST_LIT_VALUE (root->right->right) !=
3774 (getSize (TTYPE (root->left->left)) * 8 - 1))
3777 /* whew got the first case : create the AST */
3778 return newNode (RRC, root->left->left, NULL);
3782 /* fourth and last case for now */
3783 /* (?symbol << 7) | (?symbol >> 1) */
3784 if (IS_RIGHT_OP (root->right) &&
3785 IS_LEFT_OP (root->left))
3788 if (!SPEC_USIGN (TETYPE (root->left->left)))
3791 if (!IS_AST_LIT_VALUE (root->left->right) ||
3792 !IS_AST_LIT_VALUE (root->right->right))
3795 /* make sure it is the same symbol */
3796 if (!isAstEqual (root->left->left,
3800 if (AST_LIT_VALUE (root->right->right) != 1)
3803 if (AST_LIT_VALUE (root->left->right) !=
3804 (getSize (TTYPE (root->left->left)) * 8 - 1))
3807 /* whew got the first case : create the AST */
3808 return newNode (RRC, root->left->left, NULL);
3812 /* not found return root */
3816 /*-----------------------------------------------------------------*/
3817 /* optimizeCompare - otimizes compares for bit variables */
3818 /*-----------------------------------------------------------------*/
3820 optimizeCompare (ast * root)
3822 ast *optExpr = NULL;
3825 unsigned int litValue;
3827 /* if nothing then return nothing */
3831 /* if not a compare op then do leaves */
3832 if (!IS_COMPARE_OP (root))
3834 root->left = optimizeCompare (root->left);
3835 root->right = optimizeCompare (root->right);
3839 /* if left & right are the same then depending
3840 of the operation do */
3841 if (isAstEqual (root->left, root->right))
3843 switch (root->opval.op)
3848 optExpr = newAst_VALUE (constVal ("0"));
3853 optExpr = newAst_VALUE (constVal ("1"));
3857 return decorateType (optExpr);
3860 vleft = (root->left->type == EX_VALUE ?
3861 root->left->opval.val : NULL);
3863 vright = (root->right->type == EX_VALUE ?
3864 root->right->opval.val : NULL);
3866 /* if left is a BITVAR in BITSPACE */
3867 /* and right is a LITERAL then opt- */
3868 /* imize else do nothing */
3869 if (vleft && vright &&
3870 IS_BITVAR (vleft->etype) &&
3871 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3872 IS_LITERAL (vright->etype))
3875 /* if right side > 1 then comparison may never succeed */
3876 if ((litValue = (int) floatFromVal (vright)) > 1)
3878 werror (W_BAD_COMPARE);
3884 switch (root->opval.op)
3886 case '>': /* bit value greater than 1 cannot be */
3887 werror (W_BAD_COMPARE);
3891 case '<': /* bit value < 1 means 0 */
3893 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3896 case LE_OP: /* bit value <= 1 means no check */
3897 optExpr = newAst_VALUE (vright);
3900 case GE_OP: /* bit value >= 1 means only check for = */
3902 optExpr = newAst_VALUE (vleft);
3907 { /* literal is zero */
3908 switch (root->opval.op)
3910 case '<': /* bit value < 0 cannot be */
3911 werror (W_BAD_COMPARE);
3915 case '>': /* bit value > 0 means 1 */
3917 optExpr = newAst_VALUE (vleft);
3920 case LE_OP: /* bit value <= 0 means no check */
3921 case GE_OP: /* bit value >= 0 means no check */
3922 werror (W_BAD_COMPARE);
3926 case EQ_OP: /* bit == 0 means ! of bit */
3927 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3931 return decorateType (resolveSymbols (optExpr));
3932 } /* end-of-if of BITVAR */
3937 /*-----------------------------------------------------------------*/
3938 /* addSymToBlock : adds the symbol to the first block we find */
3939 /*-----------------------------------------------------------------*/
3941 addSymToBlock (symbol * sym, ast * tree)
3943 /* reached end of tree or a leaf */
3944 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3948 if (IS_AST_OP (tree) &&
3949 tree->opval.op == BLOCK)
3952 symbol *lsym = copySymbol (sym);
3954 lsym->next = AST_VALUES (tree, sym);
3955 AST_VALUES (tree, sym) = lsym;
3959 addSymToBlock (sym, tree->left);
3960 addSymToBlock (sym, tree->right);
3963 /*-----------------------------------------------------------------*/
3964 /* processRegParms - do processing for register parameters */
3965 /*-----------------------------------------------------------------*/
3967 processRegParms (value * args, ast * body)
3971 if (IS_REGPARM (args->etype))
3972 addSymToBlock (args->sym, body);
3977 /*-----------------------------------------------------------------*/
3978 /* resetParmKey - resets the operandkeys for the symbols */
3979 /*-----------------------------------------------------------------*/
3980 DEFSETFUNC (resetParmKey)
3991 /*-----------------------------------------------------------------*/
3992 /* createFunction - This is the key node that calls the iCode for */
3993 /* generating the code for a function. Note code */
3994 /* is generated function by function, later when */
3995 /* add inter-procedural analysis this will change */
3996 /*-----------------------------------------------------------------*/
3998 createFunction (symbol * name, ast * body)
4004 iCode *piCode = NULL;
4006 /* if check function return 0 then some problem */
4007 if (checkFunction (name) == 0)
4010 /* create a dummy block if none exists */
4012 body = newNode (BLOCK, NULL, NULL);
4016 /* check if the function name already in the symbol table */
4017 if ((csym = findSym (SymbolTab, NULL, name->name)))
4020 /* special case for compiler defined functions
4021 we need to add the name to the publics list : this
4022 actually means we are now compiling the compiler
4026 addSet (&publics, name);
4032 allocVariables (name);
4034 name->lastLine = yylineno;
4036 processFuncArgs (currFunc, 0);
4038 /* set the stack pointer */
4039 /* PENDING: check this for the mcs51 */
4040 stackPtr = -port->stack.direction * port->stack.call_overhead;
4041 if (IS_ISR (name->etype))
4042 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4043 if (IS_RENT (name->etype) || options.stackAuto)
4044 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4046 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4048 fetype = getSpec (name->type); /* get the specifier for the function */
4049 /* if this is a reentrant function then */
4050 if (IS_RENT (fetype))
4053 allocParms (name->args); /* allocate the parameters */
4055 /* do processing for parameters that are passed in registers */
4056 processRegParms (name->args, body);
4058 /* set the stack pointer */
4062 /* allocate & autoinit the block variables */
4063 processBlockVars (body, &stack, ALLOCATE);
4065 /* save the stack information */
4066 if (options.useXstack)
4067 name->xstack = SPEC_STAK (fetype) = stack;
4069 name->stack = SPEC_STAK (fetype) = stack;
4071 /* name needs to be mangled */
4072 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4074 body = resolveSymbols (body); /* resolve the symbols */
4075 body = decorateType (body); /* propagateType & do semantic checks */
4077 ex = newAst_VALUE (symbolVal (name)); /* create name */
4078 ex = newNode (FUNCTION, ex, body);
4079 ex->values.args = name->args;
4083 werror (E_FUNC_NO_CODE, name->name);
4087 /* create the node & generate intermediate code */
4089 codeOutFile = code->oFile;
4090 piCode = iCodeFromAst (ex);
4094 werror (E_FUNC_NO_CODE, name->name);
4098 eBBlockFromiCode (piCode);
4100 /* if there are any statics then do them */
4103 GcurMemmap = statsg;
4104 codeOutFile = statsg->oFile;
4105 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4111 /* dealloc the block variables */
4112 processBlockVars (body, &stack, DEALLOCATE);
4113 /* deallocate paramaters */
4114 deallocParms (name->args);
4116 if (IS_RENT (fetype))
4119 /* we are done freeup memory & cleanup */
4124 addSet (&operKeyReset, name);
4125 applyToSet (operKeyReset, resetParmKey);
4127 if (options.debug && !options.nodebug)
4128 cdbStructBlock (1, cdbFile);
4130 cleanUpLevel (LabelTab, 0);
4131 cleanUpBlock (StructTab, 1);
4132 cleanUpBlock (TypedefTab, 1);
4134 xstack->syms = NULL;
4135 istack->syms = NULL;