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,
540 /* create the symbol */
541 sym = newSymbol (name, 0);
543 /* if arguments required */
548 args = sym->args = newValue ();
552 argStack += getSize (type);
553 args->type = copyLinkChain (argType);
554 args->etype = getSpec (args->type);
557 args = args->next = newValue ();
561 /* setup return value */
562 sym->type = newLink ();
563 DCL_TYPE (sym->type) = FUNCTION;
564 sym->type->next = copyLinkChain (type);
565 sym->etype = getSpec (sym->type);
566 SPEC_RENT (sym->etype) = rent;
571 sym->argStack = (rent ? argStack : 0);
572 allocVariables (sym);
577 /*-----------------------------------------------------------------*/
578 /* reverseParms - will reverse a parameter tree */
579 /*-----------------------------------------------------------------*/
581 reverseParms (ast * ptree)
587 /* top down if we find a nonParm tree then quit */
588 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
591 ptree->left = ptree->right;
592 ptree->right = ttree;
593 reverseParms (ptree->left);
594 reverseParms (ptree->right);
600 /*-----------------------------------------------------------------*/
601 /* processParms - makes sure the parameters are okay and do some */
602 /* processing with them */
603 /*-----------------------------------------------------------------*/
605 processParms (ast * func,
611 sym_link *fetype = func->etype;
613 /* if none of them exist */
614 if (!defParm && !actParm)
617 /* if the function is being called via a pointer & */
618 /* it has not been defined a reentrant then we cannot */
619 /* have parameters */
620 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
622 werror (E_NONRENT_ARGS);
626 /* if defined parameters ended but actual parameters */
627 /* exist and this is not defined as a variable arg */
628 /* also check if statckAuto option is specified */
629 if ((!defParm) && actParm && (!func->hasVargs) &&
630 !options.stackAuto && !IS_RENT (fetype))
632 werror (E_TOO_MANY_PARMS);
636 /* if defined parameters present but no actual parameters */
637 if (defParm && !actParm)
639 werror (E_TOO_FEW_PARMS);
643 /* If this is a varargs function... */
644 if (!defParm && actParm && func->hasVargs)
648 if (IS_CAST_OP (actParm)
649 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
651 /* Parameter was explicitly typecast; don't touch it. */
655 /* If it's a small integer, upcast to int. */
656 if (IS_INTEGRAL (actParm->ftype)
657 && getSize (actParm->ftype) < (unsigned) INTSIZE)
659 newType = newAst_LINK (INTTYPE);
662 if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
664 newType = newAst_LINK (copyLinkChain (actParm->ftype));
665 DCL_TYPE (newType->opval.lnk) = GPOINTER;
668 if (IS_AGGREGATE (actParm->ftype))
670 newType = newAst_LINK (copyLinkChain (actParm->ftype));
671 DCL_TYPE (newType->opval.lnk) = GPOINTER;
676 /* cast required; change this op to a cast. */
677 ast *parmCopy = resolveSymbols (copyAst (actParm));
679 actParm->type = EX_OP;
680 actParm->opval.op = CAST;
681 actParm->left = newType;
682 actParm->right = parmCopy;
683 decorateType (actParm);
685 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
687 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
688 processParms (func, NULL, actParm->right, parmNumber, rightmost));
693 /* if defined parameters ended but actual has not & */
695 if (!defParm && actParm &&
696 (options.stackAuto || IS_RENT (fetype)))
699 resolveSymbols (actParm);
700 /* if this is a PARAM node then match left & right */
701 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
703 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
704 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
708 /* If we have found a value node by following only right-hand links,
709 * then we know that there are no more values after us.
711 * Therefore, if there are more defined parameters, the caller didn't
714 if (rightmost && defParm->next)
716 werror (E_TOO_FEW_PARMS);
721 /* the parameter type must be at least castable */
722 if (checkType (defParm->type, actParm->ftype) == 0)
724 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
725 werror (E_CONTINUE, "defined type ");
726 printTypeChain (defParm->type, stderr);
727 fprintf (stderr, "\n");
728 werror (E_CONTINUE, "actual type ");
729 printTypeChain (actParm->ftype, stderr);
730 fprintf (stderr, "\n");
733 /* if the parameter is castable then add the cast */
734 if (checkType (defParm->type, actParm->ftype) < 0)
736 ast *pTree = resolveSymbols (copyAst (actParm));
738 /* now change the current one to a cast */
739 actParm->type = EX_OP;
740 actParm->opval.op = CAST;
741 actParm->left = newAst_LINK (defParm->type);
742 actParm->right = pTree;
743 actParm->etype = defParm->etype;
744 actParm->ftype = defParm->type;
747 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
749 actParm->argSym = defParm->sym;
750 /* make a copy and change the regparm type to the defined parm */
751 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
752 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
756 /*-----------------------------------------------------------------*/
757 /* createIvalType - generates ival for basic types */
758 /*-----------------------------------------------------------------*/
760 createIvalType (ast * sym, sym_link * type, initList * ilist)
764 /* if initList is deep */
765 if (ilist->type == INIT_DEEP)
766 ilist = ilist->init.deep;
768 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
769 return decorateType (newNode ('=', sym, iExpr));
772 /*-----------------------------------------------------------------*/
773 /* createIvalStruct - generates initial value for structures */
774 /*-----------------------------------------------------------------*/
776 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
782 sflds = SPEC_STRUCT (type)->fields;
783 if (ilist->type != INIT_DEEP)
785 werror (E_INIT_STRUCT, "");
789 iloop = ilist->init.deep;
791 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
795 /* if we have come to end */
799 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
800 lAst = decorateType (resolveSymbols (lAst));
801 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
807 /*-----------------------------------------------------------------*/
808 /* createIvalArray - generates code for array initialization */
809 /*-----------------------------------------------------------------*/
811 createIvalArray (ast * sym, sym_link * type, initList * ilist)
815 int lcnt = 0, size = 0;
817 /* take care of the special case */
818 /* array of characters can be init */
820 if (IS_CHAR (type->next))
821 if ((rast = createIvalCharPtr (sym,
823 decorateType (resolveSymbols (list2expr (ilist))))))
825 return decorateType (resolveSymbols (rast));
827 /* not the special case */
828 if (ilist->type != INIT_DEEP)
830 werror (E_INIT_STRUCT, "");
834 iloop = ilist->init.deep;
835 lcnt = DCL_ELEM (type);
842 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
843 aSym = decorateType (resolveSymbols (aSym));
844 rast = createIval (aSym, type->next, iloop, rast);
845 iloop = (iloop ? iloop->next : NULL);
848 /* if not array limits given & we */
849 /* are out of initialisers then */
850 if (!DCL_ELEM (type) && !iloop)
853 /* no of elements given and we */
854 /* have generated for all of them */
859 /* if we have not been given a size */
860 if (!DCL_ELEM (type))
861 DCL_ELEM (type) = size;
863 return decorateType (resolveSymbols (rast));
867 /*-----------------------------------------------------------------*/
868 /* createIvalCharPtr - generates initial values for char pointers */
869 /*-----------------------------------------------------------------*/
871 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
875 /* if this is a pointer & right is a literal array then */
876 /* just assignment will do */
877 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
878 SPEC_SCLS (iexpr->etype) == S_CODE)
879 && IS_ARRAY (iexpr->ftype)))
880 return newNode ('=', sym, iexpr);
882 /* left side is an array so we have to assign each */
884 if ((IS_LITERAL (iexpr->etype) ||
885 SPEC_SCLS (iexpr->etype) == S_CODE)
886 && IS_ARRAY (iexpr->ftype))
889 /* for each character generate an assignment */
890 /* to the array element */
891 char *s = SPEC_CVAL (iexpr->etype).v_char;
896 rast = newNode (NULLOP,
900 newAst_VALUE (valueFromLit ((float) i))),
901 newAst_VALUE (valueFromLit (*s))));
905 rast = newNode (NULLOP,
909 newAst_VALUE (valueFromLit ((float) i))),
910 newAst_VALUE (valueFromLit (*s))));
911 return decorateType (resolveSymbols (rast));
917 /*-----------------------------------------------------------------*/
918 /* createIvalPtr - generates initial value for pointers */
919 /*-----------------------------------------------------------------*/
921 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
927 if (ilist->type == INIT_DEEP)
928 ilist = ilist->init.deep;
930 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
932 /* if character pointer */
933 if (IS_CHAR (type->next))
934 if ((rast = createIvalCharPtr (sym, type, iexpr)))
937 return newNode ('=', sym, iexpr);
940 /*-----------------------------------------------------------------*/
941 /* createIval - generates code for initial value */
942 /*-----------------------------------------------------------------*/
944 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
951 /* if structure then */
952 if (IS_STRUCT (type))
953 rast = createIvalStruct (sym, type, ilist);
955 /* if this is a pointer */
957 rast = createIvalPtr (sym, type, ilist);
959 /* if this is an array */
961 rast = createIvalArray (sym, type, ilist);
963 /* if type is SPECIFIER */
965 rast = createIvalType (sym, type, ilist);
967 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
969 return decorateType (resolveSymbols (rast));
972 /*-----------------------------------------------------------------*/
973 /* initAggregates - initialises aggregate variables with initv */
974 /*-----------------------------------------------------------------*/
976 initAggregates (symbol * sym, initList * ival, ast * wid)
978 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
981 /*-----------------------------------------------------------------*/
982 /* gatherAutoInit - creates assignment expressions for initial */
984 /*-----------------------------------------------------------------*/
986 gatherAutoInit (symbol * autoChain)
993 for (sym = autoChain; sym; sym = sym->next)
996 /* resolve the symbols in the ival */
998 resolveIvalSym (sym->ival);
1000 /* if this is a static variable & has an */
1001 /* initial value the code needs to be lifted */
1002 /* here to the main portion since they can be */
1003 /* initialised only once at the start */
1004 if (IS_STATIC (sym->etype) && sym->ival &&
1005 SPEC_SCLS (sym->etype) != S_CODE)
1009 /* insert the symbol into the symbol table */
1010 /* with level = 0 & name = rname */
1011 newSym = copySymbol (sym);
1012 addSym (SymbolTab, newSym, newSym->name, 0, 0);
1014 /* now lift the code to main */
1015 if (IS_AGGREGATE (sym->type))
1016 work = initAggregates (sym, sym->ival, NULL);
1018 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1019 list2expr (sym->ival));
1021 setAstLineno (work, sym->lineDef);
1025 staticAutos = newNode (NULLOP, staticAutos, work);
1032 /* if there is an initial value */
1033 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1035 if (IS_AGGREGATE (sym->type))
1036 work = initAggregates (sym, sym->ival, NULL);
1038 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1039 list2expr (sym->ival));
1041 setAstLineno (work, sym->lineDef);
1044 init = newNode (NULLOP, init, work);
1053 /*-----------------------------------------------------------------*/
1054 /* stringToSymbol - creates a symbol from a literal string */
1055 /*-----------------------------------------------------------------*/
1057 stringToSymbol (value * val)
1059 char name[SDCC_NAME_MAX + 1];
1060 static int charLbl = 0;
1063 sprintf (name, "_str_%d", charLbl++);
1064 sym = newSymbol (name, 0); /* make it @ level 0 */
1065 strcpy (sym->rname, name);
1067 /* copy the type from the value passed */
1068 sym->type = copyLinkChain (val->type);
1069 sym->etype = getSpec (sym->type);
1070 /* change to storage class & output class */
1071 SPEC_SCLS (sym->etype) = S_CODE;
1072 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1073 SPEC_STAT (sym->etype) = 1;
1074 /* make the level & block = 0 */
1075 sym->block = sym->level = 0;
1077 /* create an ival */
1078 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1083 allocVariables (sym);
1086 return symbolVal (sym);
1090 /*-----------------------------------------------------------------*/
1091 /* processBlockVars - will go thru the ast looking for block if */
1092 /* a block is found then will allocate the syms */
1093 /* will also gather the auto inits present */
1094 /*-----------------------------------------------------------------*/
1096 processBlockVars (ast * tree, int *stack, int action)
1101 /* if this is a block */
1102 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1106 if (action == ALLOCATE)
1108 autoInit = gatherAutoInit (tree->values.sym);
1109 *stack += allocVariables (tree->values.sym);
1111 /* if there are auto inits then do them */
1113 tree->left = newNode (NULLOP, autoInit, tree->left);
1115 else /* action is deallocate */
1116 deallocLocal (tree->values.sym);
1119 processBlockVars (tree->left, stack, action);
1120 processBlockVars (tree->right, stack, action);
1124 /*-----------------------------------------------------------------*/
1125 /* constExprValue - returns the value of a constant expression */
1126 /*-----------------------------------------------------------------*/
1128 constExprValue (ast * cexpr, int check)
1130 cexpr = decorateType (resolveSymbols (cexpr));
1132 /* if this is not a constant then */
1133 if (!IS_LITERAL (cexpr->ftype))
1135 /* then check if this is a literal array
1137 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1138 SPEC_CVAL (cexpr->etype).v_char &&
1139 IS_ARRAY (cexpr->ftype))
1141 value *val = valFromType (cexpr->ftype);
1142 SPEC_SCLS (val->etype) = S_LITERAL;
1143 val->sym = cexpr->opval.val->sym;
1144 val->sym->type = copyLinkChain (cexpr->ftype);
1145 val->sym->etype = getSpec (val->sym->type);
1146 strcpy (val->name, cexpr->opval.val->sym->rname);
1150 /* if we are casting a literal value then */
1151 if (IS_AST_OP (cexpr) &&
1152 cexpr->opval.op == CAST &&
1153 IS_LITERAL (cexpr->left->ftype))
1154 return valCastLiteral (cexpr->ftype,
1155 floatFromVal (cexpr->left->opval.val));
1157 if (IS_AST_VALUE (cexpr))
1158 return cexpr->opval.val;
1161 werror (E_CONST_EXPECTED, "found expression");
1166 /* return the value */
1167 return cexpr->opval.val;
1171 /*-----------------------------------------------------------------*/
1172 /* isLabelInAst - will return true if a given label is found */
1173 /*-----------------------------------------------------------------*/
1175 isLabelInAst (symbol * label, ast * tree)
1177 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1180 if (IS_AST_OP (tree) &&
1181 tree->opval.op == LABEL &&
1182 isSymbolEqual (AST_SYMBOL (tree->left), label))
1185 return isLabelInAst (label, tree->right) &&
1186 isLabelInAst (label, tree->left);
1190 /*-----------------------------------------------------------------*/
1191 /* isLoopCountable - return true if the loop count can be determi- */
1192 /* -ned at compile time . */
1193 /*-----------------------------------------------------------------*/
1195 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1196 symbol ** sym, ast ** init, ast ** end)
1199 /* the loop is considered countable if the following
1200 conditions are true :-
1202 a) initExpr :- <sym> = <const>
1203 b) condExpr :- <sym> < <const1>
1204 c) loopExpr :- <sym> ++
1207 /* first check the initExpr */
1208 if (IS_AST_OP (initExpr) &&
1209 initExpr->opval.op == '=' && /* is assignment */
1210 IS_AST_SYM_VALUE (initExpr->left))
1211 { /* left is a symbol */
1213 *sym = AST_SYMBOL (initExpr->left);
1214 *init = initExpr->right;
1219 /* for now the symbol has to be of
1221 if (!IS_INTEGRAL ((*sym)->type))
1224 /* now check condExpr */
1225 if (IS_AST_OP (condExpr))
1228 switch (condExpr->opval.op)
1231 if (IS_AST_SYM_VALUE (condExpr->left) &&
1232 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1233 IS_AST_LIT_VALUE (condExpr->right))
1235 *end = condExpr->right;
1241 if (IS_AST_OP (condExpr->left) &&
1242 condExpr->left->opval.op == '>' &&
1243 IS_AST_LIT_VALUE (condExpr->left->right) &&
1244 IS_AST_SYM_VALUE (condExpr->left->left) &&
1245 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1248 *end = newNode ('+', condExpr->left->right,
1249 newAst_VALUE (constVal ("1")));
1260 /* check loop expression is of the form <sym>++ */
1261 if (!IS_AST_OP (loopExpr))
1264 /* check if <sym> ++ */
1265 if (loopExpr->opval.op == INC_OP)
1271 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1272 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1279 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1280 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1288 if (loopExpr->opval.op == ADD_ASSIGN)
1291 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1292 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1293 IS_AST_LIT_VALUE (loopExpr->right) &&
1294 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1302 /*-----------------------------------------------------------------*/
1303 /* astHasVolatile - returns true if ast contains any volatile */
1304 /*-----------------------------------------------------------------*/
1306 astHasVolatile (ast * tree)
1311 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1314 if (IS_AST_OP (tree))
1315 return astHasVolatile (tree->left) ||
1316 astHasVolatile (tree->right);
1321 /*-----------------------------------------------------------------*/
1322 /* astHasPointer - return true if the ast contains any ptr variable */
1323 /*-----------------------------------------------------------------*/
1325 astHasPointer (ast * tree)
1330 if (IS_AST_LINK (tree))
1333 /* if we hit an array expression then check
1334 only the left side */
1335 if (IS_AST_OP (tree) && tree->opval.op == '[')
1336 return astHasPointer (tree->left);
1338 if (IS_AST_VALUE (tree))
1339 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1341 return astHasPointer (tree->left) ||
1342 astHasPointer (tree->right);
1346 /*-----------------------------------------------------------------*/
1347 /* astHasSymbol - return true if the ast has the given symbol */
1348 /*-----------------------------------------------------------------*/
1350 astHasSymbol (ast * tree, symbol * sym)
1352 if (!tree || IS_AST_LINK (tree))
1355 if (IS_AST_VALUE (tree))
1357 if (IS_AST_SYM_VALUE (tree))
1358 return isSymbolEqual (AST_SYMBOL (tree), sym);
1363 return astHasSymbol (tree->left, sym) ||
1364 astHasSymbol (tree->right, sym);
1367 /*-----------------------------------------------------------------*/
1368 /* isConformingBody - the loop body has to conform to a set of rules */
1369 /* for the loop to be considered reversible read on for rules */
1370 /*-----------------------------------------------------------------*/
1372 isConformingBody (ast * pbody, symbol * sym, ast * body)
1375 /* we are going to do a pre-order traversal of the
1376 tree && check for the following conditions. (essentially
1377 a set of very shallow tests )
1378 a) the sym passed does not participate in
1379 any arithmetic operation
1380 b) There are no function calls
1381 c) all jumps are within the body
1382 d) address of loop control variable not taken
1383 e) if an assignment has a pointer on the
1384 left hand side make sure right does not have
1385 loop control variable */
1387 /* if we reach the end or a leaf then true */
1388 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1392 /* if anything else is "volatile" */
1393 if (IS_VOLATILE (TETYPE (pbody)))
1396 /* we will walk the body in a pre-order traversal for
1398 switch (pbody->opval.op)
1400 /*------------------------------------------------------------------*/
1402 return isConformingBody (pbody->right, sym, body);
1404 /*------------------------------------------------------------------*/
1409 /*------------------------------------------------------------------*/
1410 case INC_OP: /* incerement operator unary so left only */
1413 /* sure we are not sym is not modified */
1415 IS_AST_SYM_VALUE (pbody->left) &&
1416 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1420 IS_AST_SYM_VALUE (pbody->right) &&
1421 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1426 /*------------------------------------------------------------------*/
1428 case '*': /* can be unary : if right is null then unary operation */
1433 /* if right is NULL then unary operation */
1434 /*------------------------------------------------------------------*/
1435 /*----------------------------*/
1437 /*----------------------------*/
1440 if (IS_AST_SYM_VALUE (pbody->left) &&
1441 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1444 return isConformingBody (pbody->left, sym, body);
1448 if (astHasSymbol (pbody->left, sym) ||
1449 astHasSymbol (pbody->right, sym))
1454 /*------------------------------------------------------------------*/
1462 if (IS_AST_SYM_VALUE (pbody->left) &&
1463 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1466 if (IS_AST_SYM_VALUE (pbody->right) &&
1467 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1470 return isConformingBody (pbody->left, sym, body) &&
1471 isConformingBody (pbody->right, sym, body);
1478 if (IS_AST_SYM_VALUE (pbody->left) &&
1479 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1481 return isConformingBody (pbody->left, sym, body);
1483 /*------------------------------------------------------------------*/
1495 case SIZEOF: /* evaluate wihout code generation */
1497 return isConformingBody (pbody->left, sym, body) &&
1498 isConformingBody (pbody->right, sym, body);
1500 /*------------------------------------------------------------------*/
1503 /* if left has a pointer & right has loop
1504 control variable then we cannot */
1505 if (astHasPointer (pbody->left) &&
1506 astHasSymbol (pbody->right, sym))
1508 if (astHasVolatile (pbody->left))
1511 if (IS_AST_SYM_VALUE (pbody->left) &&
1512 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1515 if (astHasVolatile (pbody->left))
1518 return isConformingBody (pbody->left, sym, body) &&
1519 isConformingBody (pbody->right, sym, body);
1530 assert ("Parser should not have generated this\n");
1532 /*------------------------------------------------------------------*/
1533 /*----------------------------*/
1534 /* comma operator */
1535 /*----------------------------*/
1537 return isConformingBody (pbody->left, sym, body) &&
1538 isConformingBody (pbody->right, sym, body);
1540 /*------------------------------------------------------------------*/
1541 /*----------------------------*/
1543 /*----------------------------*/
1547 /*------------------------------------------------------------------*/
1548 /*----------------------------*/
1549 /* return statement */
1550 /*----------------------------*/
1555 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1560 if (astHasSymbol (pbody->left, sym))
1567 return isConformingBody (pbody->left, sym, body) &&
1568 isConformingBody (pbody->right, sym, body);
1574 /*-----------------------------------------------------------------*/
1575 /* isLoopReversible - takes a for loop as input && returns true */
1576 /* if the for loop is reversible. If yes will set the value of */
1577 /* the loop control var & init value & termination value */
1578 /*-----------------------------------------------------------------*/
1580 isLoopReversible (ast * loop, symbol ** loopCntrl,
1581 ast ** init, ast ** end)
1583 /* if option says don't do it then don't */
1584 if (optimize.noLoopReverse)
1586 /* there are several tests to determine this */
1588 /* for loop has to be of the form
1589 for ( <sym> = <const1> ;
1590 [<sym> < <const2>] ;
1591 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1593 if (!isLoopCountable (AST_FOR (loop, initExpr),
1594 AST_FOR (loop, condExpr),
1595 AST_FOR (loop, loopExpr),
1596 loopCntrl, init, end))
1599 /* now do some serious checking on the body of the loop
1602 return isConformingBody (loop->left, *loopCntrl, loop->left);
1606 /*-----------------------------------------------------------------*/
1607 /* replLoopSym - replace the loop sym by loop sym -1 */
1608 /*-----------------------------------------------------------------*/
1610 replLoopSym (ast * body, symbol * sym)
1613 if (!body || IS_AST_LINK (body))
1616 if (IS_AST_SYM_VALUE (body))
1619 if (isSymbolEqual (AST_SYMBOL (body), sym))
1623 body->opval.op = '-';
1624 body->left = newAst_VALUE (symbolVal (sym));
1625 body->right = newAst_VALUE (constVal ("1"));
1633 replLoopSym (body->left, sym);
1634 replLoopSym (body->right, sym);
1638 /*-----------------------------------------------------------------*/
1639 /* reverseLoop - do the actual loop reversal */
1640 /*-----------------------------------------------------------------*/
1642 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1646 /* create the following tree
1651 if (sym) goto for_continue ;
1654 /* put it together piece by piece */
1655 rloop = newNode (NULLOP,
1656 createIf (newAst_VALUE (symbolVal (sym)),
1658 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1661 newAst_VALUE (symbolVal (sym)),
1664 replLoopSym (loop->left, sym);
1666 rloop = newNode (NULLOP,
1668 newAst_VALUE (symbolVal (sym)),
1669 newNode ('-', end, init)),
1670 createLabel (AST_FOR (loop, continueLabel),
1674 newNode (SUB_ASSIGN,
1675 newAst_VALUE (symbolVal (sym)),
1676 newAst_VALUE (constVal ("1"))),
1679 return decorateType (rloop);
1683 #define DEMAND_INTEGER_PROMOTION
1685 #ifdef DEMAND_INTEGER_PROMOTION
1687 /*-----------------------------------------------------------------*/
1688 /* walk a tree looking for the leaves. Add a typecast to the given */
1689 /* type to each value leaf node. */
1690 /*-----------------------------------------------------------------*/
1692 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1694 if (!node || IS_CALLOP(node))
1696 /* WTF? We should never get here. */
1700 if (!node->left && !node->right)
1702 /* We're at a leaf; if it's a value, apply the typecast */
1703 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1705 *parentPtr = decorateType (newNode (CAST,
1706 newAst_LINK (copyLinkChain (type)),
1714 pushTypeCastToLeaves (type, node->left, &(node->left));
1718 pushTypeCastToLeaves (type, node->right, &(node->right));
1725 /*-----------------------------------------------------------------*/
1726 /* Given an assignment operation in a tree, determine if the LHS */
1727 /* (the result) has a different (integer) type than the RHS. */
1728 /* If so, walk the RHS and add a typecast to the type of the LHS */
1729 /* to all leaf nodes. */
1730 /*-----------------------------------------------------------------*/
1732 propAsgType (ast * tree)
1734 #ifdef DEMAND_INTEGER_PROMOTION
1735 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1737 /* Nothing to do here... */
1741 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1743 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1750 /*-----------------------------------------------------------------*/
1751 /* decorateType - compute type for this tree also does type cheking */
1752 /* this is done bottom up, since type have to flow upwards */
1753 /* it also does constant folding, and paramater checking */
1754 /*-----------------------------------------------------------------*/
1756 decorateType (ast * tree)
1764 /* if already has type then do nothing */
1765 if (tree->decorated)
1768 tree->decorated = 1;
1770 /* print the line */
1771 /* if not block & function */
1772 if (tree->type == EX_OP &&
1773 (tree->opval.op != FUNCTION &&
1774 tree->opval.op != BLOCK &&
1775 tree->opval.op != NULLOP))
1777 filename = tree->filename;
1778 lineno = tree->lineno;
1781 /* if any child is an error | this one is an error do nothing */
1782 if (tree->isError ||
1783 (tree->left && tree->left->isError) ||
1784 (tree->right && tree->right->isError))
1787 /*------------------------------------------------------------------*/
1788 /*----------------------------*/
1789 /* leaf has been reached */
1790 /*----------------------------*/
1791 /* if this is of type value */
1792 /* just get the type */
1793 if (tree->type == EX_VALUE)
1796 if (IS_LITERAL (tree->opval.val->etype))
1799 /* if this is a character array then declare it */
1800 if (IS_ARRAY (tree->opval.val->type))
1801 tree->opval.val = stringToSymbol (tree->opval.val);
1803 /* otherwise just copy the type information */
1804 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1805 if (funcInChain (tree->opval.val->type))
1807 tree->hasVargs = tree->opval.val->sym->hasVargs;
1808 tree->args = copyValueChain (tree->opval.val->sym->args);
1813 if (tree->opval.val->sym)
1815 /* if the undefined flag is set then give error message */
1816 if (tree->opval.val->sym->undefined)
1818 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1820 TTYPE (tree) = TETYPE (tree) =
1821 tree->opval.val->type = tree->opval.val->sym->type =
1822 tree->opval.val->etype = tree->opval.val->sym->etype =
1823 copyLinkChain (INTTYPE);
1828 /* if impilicit i.e. struct/union member then no type */
1829 if (tree->opval.val->sym->implicit)
1830 TTYPE (tree) = TETYPE (tree) = NULL;
1835 /* else copy the type */
1836 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1838 /* and mark it as referenced */
1839 tree->opval.val->sym->isref = 1;
1840 /* if this is of type function or function pointer */
1841 if (funcInChain (tree->opval.val->type))
1843 tree->hasVargs = tree->opval.val->sym->hasVargs;
1844 tree->args = copyValueChain (tree->opval.val->sym->args);
1854 /* if type link for the case of cast */
1855 if (tree->type == EX_LINK)
1857 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1864 dtl = decorateType (tree->left);
1865 dtr = decorateType (tree->right);
1867 /* this is to take care of situations
1868 when the tree gets rewritten */
1869 if (dtl != tree->left)
1871 if (dtr != tree->right)
1875 /* depending on type of operator do */
1877 switch (tree->opval.op)
1879 /*------------------------------------------------------------------*/
1880 /*----------------------------*/
1882 /*----------------------------*/
1885 /* determine which is the array & which the index */
1886 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1889 ast *tempTree = tree->left;
1890 tree->left = tree->right;
1891 tree->right = tempTree;
1894 /* first check if this is a array or a pointer */
1895 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1897 werror (E_NEED_ARRAY_PTR, "[]");
1898 goto errorTreeReturn;
1901 /* check if the type of the idx */
1902 if (!IS_INTEGRAL (RTYPE (tree)))
1904 werror (E_IDX_NOT_INT);
1905 goto errorTreeReturn;
1908 /* if the left is an rvalue then error */
1911 werror (E_LVALUE_REQUIRED, "array access");
1912 goto errorTreeReturn;
1915 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1916 if (IS_PTR(LTYPE(tree))) {
1917 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1921 /*------------------------------------------------------------------*/
1922 /*----------------------------*/
1924 /*----------------------------*/
1926 /* if this is not a structure */
1927 if (!IS_STRUCT (LTYPE (tree)))
1929 werror (E_STRUCT_UNION, ".");
1930 goto errorTreeReturn;
1932 TTYPE (tree) = structElemType (LTYPE (tree),
1933 (tree->right->type == EX_VALUE ?
1934 tree->right->opval.val : NULL), &tree->args);
1935 TETYPE (tree) = getSpec (TTYPE (tree));
1938 /*------------------------------------------------------------------*/
1939 /*----------------------------*/
1940 /* struct/union pointer */
1941 /*----------------------------*/
1943 /* if not pointer to a structure */
1944 if (!IS_PTR (LTYPE (tree)))
1946 werror (E_PTR_REQD);
1947 goto errorTreeReturn;
1950 if (!IS_STRUCT (LTYPE (tree)->next))
1952 werror (E_STRUCT_UNION, "->");
1953 goto errorTreeReturn;
1956 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1957 (tree->right->type == EX_VALUE ?
1958 tree->right->opval.val : NULL), &tree->args);
1959 TETYPE (tree) = getSpec (TTYPE (tree));
1962 /*------------------------------------------------------------------*/
1963 /*----------------------------*/
1964 /* ++/-- operation */
1965 /*----------------------------*/
1966 case INC_OP: /* incerement operator unary so left only */
1969 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1970 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1971 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
1972 werror (E_CODE_WRITE, "++/--");
1981 /*------------------------------------------------------------------*/
1982 /*----------------------------*/
1984 /*----------------------------*/
1985 case '&': /* can be unary */
1986 /* if right is NULL then unary operation */
1987 if (tree->right) /* not an unary operation */
1990 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1992 werror (E_BITWISE_OP);
1993 werror (E_CONTINUE, "left & right types are ");
1994 printTypeChain (LTYPE (tree), stderr);
1995 fprintf (stderr, ",");
1996 printTypeChain (RTYPE (tree), stderr);
1997 fprintf (stderr, "\n");
1998 goto errorTreeReturn;
2001 /* if they are both literal */
2002 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2004 tree->type = EX_VALUE;
2005 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2006 valFromType (RETYPE (tree)), '&');
2008 tree->right = tree->left = NULL;
2009 TETYPE (tree) = tree->opval.val->etype;
2010 TTYPE (tree) = tree->opval.val->type;
2014 /* see if this is a GETHBIT operation if yes
2017 ast *otree = optimizeGetHbit (tree);
2020 return decorateType (otree);
2023 /* if right or left is literal then result of that type */
2024 if (IS_LITERAL (RTYPE (tree)))
2027 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2028 TETYPE (tree) = getSpec (TTYPE (tree));
2029 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2033 if (IS_LITERAL (LTYPE (tree)))
2035 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2036 TETYPE (tree) = getSpec (TTYPE (tree));
2037 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2043 computeType (LTYPE (tree), RTYPE (tree));
2044 TETYPE (tree) = getSpec (TTYPE (tree));
2047 LRVAL (tree) = RRVAL (tree) = 1;
2051 /*------------------------------------------------------------------*/
2052 /*----------------------------*/
2054 /*----------------------------*/
2056 p->class = DECLARATOR;
2057 /* if bit field then error */
2058 if (IS_BITVAR (tree->left->etype))
2060 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2061 goto errorTreeReturn;
2064 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2066 werror (E_ILLEGAL_ADDR, "address of register variable");
2067 goto errorTreeReturn;
2070 if (IS_FUNC (LTYPE (tree)))
2072 werror (E_ILLEGAL_ADDR, "address of function");
2073 goto errorTreeReturn;
2078 werror (E_LVALUE_REQUIRED, "address of");
2079 goto errorTreeReturn;
2081 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2083 DCL_TYPE (p) = CPOINTER;
2084 DCL_PTR_CONST (p) = port->mem.code_ro;
2086 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2087 DCL_TYPE (p) = FPOINTER;
2088 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2089 DCL_TYPE (p) = PPOINTER;
2090 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2091 DCL_TYPE (p) = IPOINTER;
2092 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2093 DCL_TYPE (p) = EEPPOINTER;
2095 DCL_TYPE (p) = POINTER;
2097 if (IS_AST_SYM_VALUE (tree->left))
2099 AST_SYMBOL (tree->left)->addrtaken = 1;
2100 AST_SYMBOL (tree->left)->allocreq = 1;
2103 p->next = LTYPE (tree);
2105 TETYPE (tree) = getSpec (TTYPE (tree));
2106 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2107 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2112 /*------------------------------------------------------------------*/
2113 /*----------------------------*/
2115 /*----------------------------*/
2117 /* if the rewrite succeeds then don't go any furthur */
2119 ast *wtree = optimizeRRCRLC (tree);
2121 return decorateType (wtree);
2123 /*------------------------------------------------------------------*/
2124 /*----------------------------*/
2126 /*----------------------------*/
2128 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2130 werror (E_BITWISE_OP);
2131 werror (E_CONTINUE, "left & right types are ");
2132 printTypeChain (LTYPE (tree), stderr);
2133 fprintf (stderr, ",");
2134 printTypeChain (RTYPE (tree), stderr);
2135 fprintf (stderr, "\n");
2136 goto errorTreeReturn;
2139 /* if they are both literal then */
2140 /* rewrite the tree */
2141 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2143 tree->type = EX_VALUE;
2144 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2145 valFromType (RETYPE (tree)),
2147 tree->right = tree->left = NULL;
2148 TETYPE (tree) = tree->opval.val->etype;
2149 TTYPE (tree) = tree->opval.val->type;
2152 LRVAL (tree) = RRVAL (tree) = 1;
2153 TETYPE (tree) = getSpec (TTYPE (tree) =
2154 computeType (LTYPE (tree),
2157 /*------------------------------------------------------------------*/
2158 /*----------------------------*/
2160 /*----------------------------*/
2162 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2164 werror (E_INVALID_OP, "divide");
2165 goto errorTreeReturn;
2167 /* if they are both literal then */
2168 /* rewrite the tree */
2169 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2171 tree->type = EX_VALUE;
2172 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2173 valFromType (RETYPE (tree)));
2174 tree->right = tree->left = NULL;
2175 TETYPE (tree) = getSpec (TTYPE (tree) =
2176 tree->opval.val->type);
2179 LRVAL (tree) = RRVAL (tree) = 1;
2180 TETYPE (tree) = getSpec (TTYPE (tree) =
2181 computeType (LTYPE (tree),
2185 /*------------------------------------------------------------------*/
2186 /*----------------------------*/
2188 /*----------------------------*/
2190 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2192 werror (E_BITWISE_OP);
2193 werror (E_CONTINUE, "left & right types are ");
2194 printTypeChain (LTYPE (tree), stderr);
2195 fprintf (stderr, ",");
2196 printTypeChain (RTYPE (tree), stderr);
2197 fprintf (stderr, "\n");
2198 goto errorTreeReturn;
2200 /* if they are both literal then */
2201 /* rewrite the tree */
2202 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2204 tree->type = EX_VALUE;
2205 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2206 valFromType (RETYPE (tree)));
2207 tree->right = tree->left = NULL;
2208 TETYPE (tree) = getSpec (TTYPE (tree) =
2209 tree->opval.val->type);
2212 LRVAL (tree) = RRVAL (tree) = 1;
2213 TETYPE (tree) = getSpec (TTYPE (tree) =
2214 computeType (LTYPE (tree),
2218 /*------------------------------------------------------------------*/
2219 /*----------------------------*/
2220 /* address dereference */
2221 /*----------------------------*/
2222 case '*': /* can be unary : if right is null then unary operation */
2225 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2227 werror (E_PTR_REQD);
2228 goto errorTreeReturn;
2233 werror (E_LVALUE_REQUIRED, "pointer deref");
2234 goto errorTreeReturn;
2236 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2237 LTYPE (tree)->next : NULL);
2238 TETYPE (tree) = getSpec (TTYPE (tree));
2239 tree->args = tree->left->args;
2240 tree->hasVargs = tree->left->hasVargs;
2241 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2245 /*------------------------------------------------------------------*/
2246 /*----------------------------*/
2247 /* multiplication */
2248 /*----------------------------*/
2249 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2251 werror (E_INVALID_OP, "multiplication");
2252 goto errorTreeReturn;
2255 /* if they are both literal then */
2256 /* rewrite the tree */
2257 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2259 tree->type = EX_VALUE;
2260 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2261 valFromType (RETYPE (tree)));
2262 tree->right = tree->left = NULL;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 tree->opval.val->type);
2268 /* if left is a literal exchange left & right */
2269 if (IS_LITERAL (LTYPE (tree)))
2271 ast *tTree = tree->left;
2272 tree->left = tree->right;
2273 tree->right = tTree;
2276 LRVAL (tree) = RRVAL (tree) = 1;
2277 /* promote result to int if left & right are char / short
2278 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2279 if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) &&
2280 (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
2281 TETYPE (tree) = getSpec (TTYPE (tree) =
2282 computeType (LTYPE (tree),
2284 SPEC_NOUN(TETYPE(tree)) = V_INT;
2285 SPEC_SHORT(TETYPE(tree))=0;
2287 TETYPE (tree) = getSpec (TTYPE (tree) =
2288 computeType (LTYPE (tree),
2293 /*------------------------------------------------------------------*/
2294 /*----------------------------*/
2295 /* unary '+' operator */
2296 /*----------------------------*/
2301 if (!IS_INTEGRAL (LTYPE (tree)))
2303 werror (E_UNARY_OP, '+');
2304 goto errorTreeReturn;
2307 /* if left is a literal then do it */
2308 if (IS_LITERAL (LTYPE (tree)))
2310 tree->type = EX_VALUE;
2311 tree->opval.val = valFromType (LETYPE (tree));
2313 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2317 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2321 /*------------------------------------------------------------------*/
2322 /*----------------------------*/
2324 /*----------------------------*/
2326 /* this is not a unary operation */
2327 /* if both pointers then problem */
2328 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2329 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2331 werror (E_PTR_PLUS_PTR);
2332 goto errorTreeReturn;
2335 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2336 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2338 werror (E_PLUS_INVALID, "+");
2339 goto errorTreeReturn;
2342 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2343 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2345 werror (E_PLUS_INVALID, "+");
2346 goto errorTreeReturn;
2348 /* if they are both literal then */
2349 /* rewrite the tree */
2350 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2352 tree->type = EX_VALUE;
2353 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2354 valFromType (RETYPE (tree)));
2355 tree->right = tree->left = NULL;
2356 TETYPE (tree) = getSpec (TTYPE (tree) =
2357 tree->opval.val->type);
2361 /* if the right is a pointer or left is a literal
2362 xchange left & right */
2363 if (IS_ARRAY (RTYPE (tree)) ||
2364 IS_PTR (RTYPE (tree)) ||
2365 IS_LITERAL (LTYPE (tree)))
2367 ast *tTree = tree->left;
2368 tree->left = tree->right;
2369 tree->right = tTree;
2372 LRVAL (tree) = RRVAL (tree) = 1;
2373 /* if the left is a pointer */
2374 if (IS_PTR (LTYPE (tree)))
2375 TETYPE (tree) = getSpec (TTYPE (tree) =
2378 TETYPE (tree) = getSpec (TTYPE (tree) =
2379 computeType (LTYPE (tree),
2383 /*------------------------------------------------------------------*/
2384 /*----------------------------*/
2386 /*----------------------------*/
2387 case '-': /* can be unary */
2388 /* if right is null then unary */
2392 if (!IS_ARITHMETIC (LTYPE (tree)))
2394 werror (E_UNARY_OP, tree->opval.op);
2395 goto errorTreeReturn;
2398 /* if left is a literal then do it */
2399 if (IS_LITERAL (LTYPE (tree)))
2401 tree->type = EX_VALUE;
2402 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2404 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2405 SPEC_USIGN(TETYPE(tree)) = 0;
2409 TTYPE (tree) = LTYPE (tree);
2413 /*------------------------------------------------------------------*/
2414 /*----------------------------*/
2416 /*----------------------------*/
2418 if (!(IS_PTR (LTYPE (tree)) ||
2419 IS_ARRAY (LTYPE (tree)) ||
2420 IS_ARITHMETIC (LTYPE (tree))))
2422 werror (E_PLUS_INVALID, "-");
2423 goto errorTreeReturn;
2426 if (!(IS_PTR (RTYPE (tree)) ||
2427 IS_ARRAY (RTYPE (tree)) ||
2428 IS_ARITHMETIC (RTYPE (tree))))
2430 werror (E_PLUS_INVALID, "-");
2431 goto errorTreeReturn;
2434 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2435 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2436 IS_INTEGRAL (RTYPE (tree))))
2438 werror (E_PLUS_INVALID, "-");
2439 goto errorTreeReturn;
2442 /* if they are both literal then */
2443 /* rewrite the tree */
2444 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2446 tree->type = EX_VALUE;
2447 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2448 valFromType (RETYPE (tree)));
2449 tree->right = tree->left = NULL;
2450 TETYPE (tree) = getSpec (TTYPE (tree) =
2451 tree->opval.val->type);
2455 /* if the left & right are equal then zero */
2456 if (isAstEqual (tree->left, tree->right))
2458 tree->type = EX_VALUE;
2459 tree->left = tree->right = NULL;
2460 tree->opval.val = constVal ("0");
2461 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2465 /* if both of them are pointers or arrays then */
2466 /* the result is going to be an integer */
2467 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2468 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2469 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2471 /* if only the left is a pointer */
2472 /* then result is a pointer */
2473 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2474 TETYPE (tree) = getSpec (TTYPE (tree) =
2477 TETYPE (tree) = getSpec (TTYPE (tree) =
2478 computeType (LTYPE (tree),
2480 LRVAL (tree) = RRVAL (tree) = 1;
2483 /*------------------------------------------------------------------*/
2484 /*----------------------------*/
2486 /*----------------------------*/
2488 /* can be only integral type */
2489 if (!IS_INTEGRAL (LTYPE (tree)))
2491 werror (E_UNARY_OP, tree->opval.op);
2492 goto errorTreeReturn;
2495 /* if left is a literal then do it */
2496 if (IS_LITERAL (LTYPE (tree)))
2498 tree->type = EX_VALUE;
2499 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2501 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2505 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2508 /*------------------------------------------------------------------*/
2509 /*----------------------------*/
2511 /*----------------------------*/
2513 /* can be pointer */
2514 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2515 !IS_PTR (LTYPE (tree)) &&
2516 !IS_ARRAY (LTYPE (tree)))
2518 werror (E_UNARY_OP, tree->opval.op);
2519 goto errorTreeReturn;
2522 /* if left is a literal then do it */
2523 if (IS_LITERAL (LTYPE (tree)))
2525 tree->type = EX_VALUE;
2526 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2528 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2532 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2535 /*------------------------------------------------------------------*/
2536 /*----------------------------*/
2538 /*----------------------------*/
2541 TTYPE (tree) = LTYPE (tree);
2542 TETYPE (tree) = LETYPE (tree);
2546 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2551 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2553 werror (E_SHIFT_OP_INVALID);
2554 werror (E_CONTINUE, "left & right types are ");
2555 printTypeChain (LTYPE (tree), stderr);
2556 fprintf (stderr, ",");
2557 printTypeChain (RTYPE (tree), stderr);
2558 fprintf (stderr, "\n");
2559 goto errorTreeReturn;
2562 /* if they are both literal then */
2563 /* rewrite the tree */
2564 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2566 tree->type = EX_VALUE;
2567 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2568 valFromType (RETYPE (tree)),
2569 (tree->opval.op == LEFT_OP ? 1 : 0));
2570 tree->right = tree->left = NULL;
2571 TETYPE (tree) = getSpec (TTYPE (tree) =
2572 tree->opval.val->type);
2575 /* if only the right side is a literal & we are
2576 shifting more than size of the left operand then zero */
2577 if (IS_LITERAL (RTYPE (tree)) &&
2578 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2579 (getSize (LTYPE (tree)) * 8))
2581 werror (W_SHIFT_CHANGED,
2582 (tree->opval.op == LEFT_OP ? "left" : "right"));
2583 tree->type = EX_VALUE;
2584 tree->left = tree->right = NULL;
2585 tree->opval.val = constVal ("0");
2586 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2589 LRVAL (tree) = RRVAL (tree) = 1;
2590 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2592 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2596 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2600 /*------------------------------------------------------------------*/
2601 /*----------------------------*/
2603 /*----------------------------*/
2604 case CAST: /* change the type */
2605 /* cannot cast to an aggregate type */
2606 if (IS_AGGREGATE (LTYPE (tree)))
2608 werror (E_CAST_ILLEGAL);
2609 goto errorTreeReturn;
2612 /* if the right is a literal replace the tree */
2613 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2615 tree->type = EX_VALUE;
2617 valCastLiteral (LTYPE (tree),
2618 floatFromVal (valFromType (RETYPE (tree))));
2621 TTYPE (tree) = tree->opval.val->type;
2622 tree->values.literalFromCast = 1;
2626 TTYPE (tree) = LTYPE (tree);
2630 TETYPE (tree) = getSpec (TTYPE (tree));
2634 /*------------------------------------------------------------------*/
2635 /*----------------------------*/
2636 /* logical &&, || */
2637 /*----------------------------*/
2640 /* each must me arithmetic type or be a pointer */
2641 if (!IS_PTR (LTYPE (tree)) &&
2642 !IS_ARRAY (LTYPE (tree)) &&
2643 !IS_INTEGRAL (LTYPE (tree)))
2645 werror (E_COMPARE_OP);
2646 goto errorTreeReturn;
2649 if (!IS_PTR (RTYPE (tree)) &&
2650 !IS_ARRAY (RTYPE (tree)) &&
2651 !IS_INTEGRAL (RTYPE (tree)))
2653 werror (E_COMPARE_OP);
2654 goto errorTreeReturn;
2656 /* if they are both literal then */
2657 /* rewrite the tree */
2658 if (IS_LITERAL (RTYPE (tree)) &&
2659 IS_LITERAL (LTYPE (tree)))
2661 tree->type = EX_VALUE;
2662 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2663 valFromType (RETYPE (tree)),
2665 tree->right = tree->left = NULL;
2666 TETYPE (tree) = getSpec (TTYPE (tree) =
2667 tree->opval.val->type);
2670 LRVAL (tree) = RRVAL (tree) = 1;
2671 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2674 /*------------------------------------------------------------------*/
2675 /*----------------------------*/
2676 /* comparison operators */
2677 /*----------------------------*/
2685 ast *lt = optimizeCompare (tree);
2691 /* if they are pointers they must be castable */
2692 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2694 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2696 werror (E_COMPARE_OP);
2697 fprintf (stderr, "comparing type ");
2698 printTypeChain (LTYPE (tree), stderr);
2699 fprintf (stderr, "to type ");
2700 printTypeChain (RTYPE (tree), stderr);
2701 fprintf (stderr, "\n");
2702 goto errorTreeReturn;
2705 /* else they should be promotable to one another */
2708 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2709 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2711 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2713 werror (E_COMPARE_OP);
2714 fprintf (stderr, "comparing type ");
2715 printTypeChain (LTYPE (tree), stderr);
2716 fprintf (stderr, "to type ");
2717 printTypeChain (RTYPE (tree), stderr);
2718 fprintf (stderr, "\n");
2719 goto errorTreeReturn;
2723 /* if they are both literal then */
2724 /* rewrite the tree */
2725 if (IS_LITERAL (RTYPE (tree)) &&
2726 IS_LITERAL (LTYPE (tree)))
2728 tree->type = EX_VALUE;
2729 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2730 valFromType (RETYPE (tree)),
2732 tree->right = tree->left = NULL;
2733 TETYPE (tree) = getSpec (TTYPE (tree) =
2734 tree->opval.val->type);
2737 LRVAL (tree) = RRVAL (tree) = 1;
2738 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2741 /*------------------------------------------------------------------*/
2742 /*----------------------------*/
2744 /*----------------------------*/
2745 case SIZEOF: /* evaluate wihout code generation */
2746 /* change the type to a integer */
2747 tree->type = EX_VALUE;
2748 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2749 tree->opval.val = constVal (buffer);
2750 tree->right = tree->left = NULL;
2751 TETYPE (tree) = getSpec (TTYPE (tree) =
2752 tree->opval.val->type);
2755 /*------------------------------------------------------------------*/
2756 /*----------------------------*/
2757 /* conditional operator '?' */
2758 /*----------------------------*/
2760 /* the type is one on the left */
2761 TTYPE (tree) = LTYPE (tree);
2762 TETYPE (tree) = getSpec (TTYPE (tree));
2766 /* if they don't match we have a problem */
2767 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2769 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2770 goto errorTreeReturn;
2773 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2774 TETYPE (tree) = getSpec (TTYPE (tree));
2778 /*------------------------------------------------------------------*/
2779 /*----------------------------*/
2780 /* assignment operators */
2781 /*----------------------------*/
2784 /* for these it must be both must be integral */
2785 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2786 !IS_ARITHMETIC (RTYPE (tree)))
2788 werror (E_OPS_INTEGRAL);
2789 goto errorTreeReturn;
2792 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2794 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2795 werror (E_CODE_WRITE, " ");
2799 werror (E_LVALUE_REQUIRED, "*= or /=");
2800 goto errorTreeReturn;
2813 /* for these it must be both must be integral */
2814 if (!IS_INTEGRAL (LTYPE (tree)) ||
2815 !IS_INTEGRAL (RTYPE (tree)))
2817 werror (E_OPS_INTEGRAL);
2818 goto errorTreeReturn;
2821 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2823 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2824 werror (E_CODE_WRITE, " ");
2828 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2829 goto errorTreeReturn;
2837 /*------------------------------------------------------------------*/
2838 /*----------------------------*/
2840 /*----------------------------*/
2842 if (!(IS_PTR (LTYPE (tree)) ||
2843 IS_ARITHMETIC (LTYPE (tree))))
2845 werror (E_PLUS_INVALID, "-=");
2846 goto errorTreeReturn;
2849 if (!(IS_PTR (RTYPE (tree)) ||
2850 IS_ARITHMETIC (RTYPE (tree))))
2852 werror (E_PLUS_INVALID, "-=");
2853 goto errorTreeReturn;
2856 TETYPE (tree) = getSpec (TTYPE (tree) =
2857 computeType (LTYPE (tree),
2860 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2861 werror (E_CODE_WRITE, " ");
2865 werror (E_LVALUE_REQUIRED, "-=");
2866 goto errorTreeReturn;
2874 /*------------------------------------------------------------------*/
2875 /*----------------------------*/
2877 /*----------------------------*/
2879 /* this is not a unary operation */
2880 /* if both pointers then problem */
2881 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2883 werror (E_PTR_PLUS_PTR);
2884 goto errorTreeReturn;
2887 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2889 werror (E_PLUS_INVALID, "+=");
2890 goto errorTreeReturn;
2893 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2895 werror (E_PLUS_INVALID, "+=");
2896 goto errorTreeReturn;
2899 TETYPE (tree) = getSpec (TTYPE (tree) =
2900 computeType (LTYPE (tree),
2903 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2904 werror (E_CODE_WRITE, " ");
2908 werror (E_LVALUE_REQUIRED, "+=");
2909 goto errorTreeReturn;
2912 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2913 tree->opval.op = '=';
2919 /*------------------------------------------------------------------*/
2920 /*----------------------------*/
2921 /* straight assignemnt */
2922 /*----------------------------*/
2924 /* cannot be an aggregate */
2925 if (IS_AGGREGATE (LTYPE (tree)))
2927 werror (E_AGGR_ASSIGN);
2928 goto errorTreeReturn;
2931 /* they should either match or be castable */
2932 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2934 werror (E_TYPE_MISMATCH, "assignment", " ");
2935 fprintf (stderr, "type --> '");
2936 printTypeChain (RTYPE (tree), stderr);
2937 fprintf (stderr, "' ");
2938 fprintf (stderr, "assigned to type --> '");
2939 printTypeChain (LTYPE (tree), stderr);
2940 fprintf (stderr, "'\n");
2941 goto errorTreeReturn;
2944 /* if the left side of the tree is of type void
2945 then report error */
2946 if (IS_VOID (LTYPE (tree)))
2948 werror (E_CAST_ZERO);
2949 fprintf (stderr, "type --> '");
2950 printTypeChain (RTYPE (tree), stderr);
2951 fprintf (stderr, "' ");
2952 fprintf (stderr, "assigned to type --> '");
2953 printTypeChain (LTYPE (tree), stderr);
2954 fprintf (stderr, "'\n");
2957 /* extra checks for pointer types */
2958 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2959 !IS_GENPTR (LTYPE (tree)))
2961 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2962 werror (W_PTR_ASSIGN);
2965 TETYPE (tree) = getSpec (TTYPE (tree) =
2969 if (!tree->initMode ) {
2970 if (IS_CONSTANT (LETYPE (tree))) {
2971 werror (E_CODE_WRITE, " ");
2976 werror (E_LVALUE_REQUIRED, "=");
2977 goto errorTreeReturn;
2984 /*------------------------------------------------------------------*/
2985 /*----------------------------*/
2986 /* comma operator */
2987 /*----------------------------*/
2989 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
2992 /*------------------------------------------------------------------*/
2993 /*----------------------------*/
2995 /*----------------------------*/
2999 if (processParms (tree->left,
3001 tree->right, &parmNumber, TRUE))
3002 goto errorTreeReturn;
3004 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3006 tree->left->args = reverseVal (tree->left->args);
3007 reverseParms (tree->right);
3010 tree->args = tree->left->args;
3011 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3014 /*------------------------------------------------------------------*/
3015 /*----------------------------*/
3016 /* return statement */
3017 /*----------------------------*/
3022 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3024 werror (E_RETURN_MISMATCH);
3025 goto errorTreeReturn;
3028 if (IS_VOID (currFunc->type->next)
3030 !IS_VOID (RTYPE (tree)))
3032 werror (E_FUNC_VOID);
3033 goto errorTreeReturn;
3036 /* if there is going to be a casing required then add it */
3037 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3039 #if 0 && defined DEMAND_INTEGER_PROMOTION
3040 if (IS_INTEGRAL (currFunc->type->next))
3042 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3048 decorateType (newNode (CAST,
3049 newAst_LINK (copyLinkChain (currFunc->type->next)),
3059 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3061 werror (E_VOID_FUNC, currFunc->name);
3062 goto errorTreeReturn;
3065 TTYPE (tree) = TETYPE (tree) = NULL;
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3070 /* switch statement */
3071 /*----------------------------*/
3073 /* the switch value must be an integer */
3074 if (!IS_INTEGRAL (LTYPE (tree)))
3076 werror (E_SWITCH_NON_INTEGER);
3077 goto errorTreeReturn;
3080 TTYPE (tree) = TETYPE (tree) = NULL;
3083 /*------------------------------------------------------------------*/
3084 /*----------------------------*/
3086 /*----------------------------*/
3088 tree->left = backPatchLabels (tree->left,
3091 TTYPE (tree) = TETYPE (tree) = NULL;
3094 /*------------------------------------------------------------------*/
3095 /*----------------------------*/
3097 /*----------------------------*/
3100 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3101 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3102 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3104 /* if the for loop is reversible then
3105 reverse it otherwise do what we normally
3111 if (isLoopReversible (tree, &sym, &init, &end))
3112 return reverseLoop (tree, sym, init, end);
3114 return decorateType (createFor (AST_FOR (tree, trueLabel),
3115 AST_FOR (tree, continueLabel),
3116 AST_FOR (tree, falseLabel),
3117 AST_FOR (tree, condLabel),
3118 AST_FOR (tree, initExpr),
3119 AST_FOR (tree, condExpr),
3120 AST_FOR (tree, loopExpr),
3124 TTYPE (tree) = TETYPE (tree) = NULL;
3128 /* some error found this tree will be killed */
3130 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3131 tree->opval.op = NULLOP;
3137 /*-----------------------------------------------------------------*/
3138 /* sizeofOp - processes size of operation */
3139 /*-----------------------------------------------------------------*/
3141 sizeofOp (sym_link * type)
3145 /* get the size and convert it to character */
3146 sprintf (buff, "%d", getSize (type));
3148 /* now convert into value */
3149 return constVal (buff);
3153 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3154 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3155 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3156 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3157 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3158 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3159 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3161 /*-----------------------------------------------------------------*/
3162 /* backPatchLabels - change and or not operators to flow control */
3163 /*-----------------------------------------------------------------*/
3165 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3171 if (!(IS_ANDORNOT (tree)))
3174 /* if this an and */
3177 static int localLbl = 0;
3180 sprintf (buffer, "_and_%d", localLbl++);
3181 localLabel = newSymbol (buffer, NestLevel);
3183 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3185 /* if left is already a IFX then just change the if true label in that */
3186 if (!IS_IFX (tree->left))
3187 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3189 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3190 /* right is a IFX then just join */
3191 if (IS_IFX (tree->right))
3192 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3194 tree->right = createLabel (localLabel, tree->right);
3195 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3197 return newNode (NULLOP, tree->left, tree->right);
3200 /* if this is an or operation */
3203 static int localLbl = 0;
3206 sprintf (buffer, "_or_%d", localLbl++);
3207 localLabel = newSymbol (buffer, NestLevel);
3209 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3211 /* if left is already a IFX then just change the if true label in that */
3212 if (!IS_IFX (tree->left))
3213 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3215 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3216 /* right is a IFX then just join */
3217 if (IS_IFX (tree->right))
3218 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3220 tree->right = createLabel (localLabel, tree->right);
3221 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3223 return newNode (NULLOP, tree->left, tree->right);
3229 int wasnot = IS_NOT (tree->left);
3230 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3232 /* if the left is already a IFX */
3233 if (!IS_IFX (tree->left))
3234 tree->left = newNode (IFX, tree->left, NULL);
3238 tree->left->trueLabel = trueLabel;
3239 tree->left->falseLabel = falseLabel;
3243 tree->left->trueLabel = falseLabel;
3244 tree->left->falseLabel = trueLabel;
3251 tree->trueLabel = trueLabel;
3252 tree->falseLabel = falseLabel;
3259 /*-----------------------------------------------------------------*/
3260 /* createBlock - create expression tree for block */
3261 /*-----------------------------------------------------------------*/
3263 createBlock (symbol * decl, ast * body)
3267 /* if the block has nothing */
3271 ex = newNode (BLOCK, NULL, body);
3272 ex->values.sym = decl;
3274 ex->right = ex->right;
3280 /*-----------------------------------------------------------------*/
3281 /* createLabel - creates the expression tree for labels */
3282 /*-----------------------------------------------------------------*/
3284 createLabel (symbol * label, ast * stmnt)
3287 char name[SDCC_NAME_MAX + 1];
3290 /* must create fresh symbol if the symbol name */
3291 /* exists in the symbol table, since there can */
3292 /* be a variable with the same name as the labl */
3293 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3294 (csym->level == label->level))
3295 label = newSymbol (label->name, label->level);
3297 /* change the name before putting it in add _ */
3298 sprintf (name, "%s", label->name);
3300 /* put the label in the LabelSymbol table */
3301 /* but first check if a label of the same */
3303 if ((csym = findSym (LabelTab, NULL, name)))
3304 werror (E_DUPLICATE_LABEL, label->name);
3306 addSym (LabelTab, label, name, label->level, 0);
3309 label->key = labelKey++;
3310 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3316 /*-----------------------------------------------------------------*/
3317 /* createCase - generates the parsetree for a case statement */
3318 /*-----------------------------------------------------------------*/
3320 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3322 char caseLbl[SDCC_NAME_MAX + 1];
3326 /* if the switch statement does not exist */
3327 /* then case is out of context */
3330 werror (E_CASE_CONTEXT);
3334 caseVal = decorateType (resolveSymbols (caseVal));
3335 /* if not a constant then error */
3336 if (!IS_LITERAL (caseVal->ftype))
3338 werror (E_CASE_CONSTANT);
3342 /* if not a integer than error */
3343 if (!IS_INTEGRAL (caseVal->ftype))
3345 werror (E_CASE_NON_INTEGER);
3349 /* find the end of the switch values chain */
3350 if (!(val = swStat->values.switchVals.swVals))
3351 swStat->values.switchVals.swVals = caseVal->opval.val;
3354 /* also order the cases according to value */
3356 int cVal = (int) floatFromVal (caseVal->opval.val);
3357 while (val && (int) floatFromVal (val) < cVal)
3363 /* if we reached the end then */
3366 pval->next = caseVal->opval.val;
3370 /* we found a value greater than */
3371 /* the current value we must add this */
3372 /* before the value */
3373 caseVal->opval.val->next = val;
3375 /* if this was the first in chain */
3376 if (swStat->values.switchVals.swVals == val)
3377 swStat->values.switchVals.swVals =
3380 pval->next = caseVal->opval.val;
3385 /* create the case label */
3386 sprintf (caseLbl, "_case_%d_%d",
3387 swStat->values.switchVals.swNum,
3388 (int) floatFromVal (caseVal->opval.val));
3390 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3395 /*-----------------------------------------------------------------*/
3396 /* createDefault - creates the parse tree for the default statement */
3397 /*-----------------------------------------------------------------*/
3399 createDefault (ast * swStat, ast * stmnt)
3401 char defLbl[SDCC_NAME_MAX + 1];
3403 /* if the switch statement does not exist */
3404 /* then case is out of context */
3407 werror (E_CASE_CONTEXT);
3411 /* turn on the default flag */
3412 swStat->values.switchVals.swDefault = 1;
3414 /* create the label */
3415 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3416 return createLabel (newSymbol (defLbl, 0), stmnt);
3419 /*-----------------------------------------------------------------*/
3420 /* createIf - creates the parsetree for the if statement */
3421 /*-----------------------------------------------------------------*/
3423 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3425 static int Lblnum = 0;
3427 symbol *ifTrue, *ifFalse, *ifEnd;
3429 /* if neither exists */
3430 if (!elseBody && !ifBody)
3433 /* create the labels */
3434 sprintf (buffer, "_iffalse_%d", Lblnum);
3435 ifFalse = newSymbol (buffer, NestLevel);
3436 /* if no else body then end == false */
3441 sprintf (buffer, "_ifend_%d", Lblnum);
3442 ifEnd = newSymbol (buffer, NestLevel);
3445 sprintf (buffer, "_iftrue_%d", Lblnum);
3446 ifTrue = newSymbol (buffer, NestLevel);
3450 /* attach the ifTrue label to the top of it body */
3451 ifBody = createLabel (ifTrue, ifBody);
3452 /* attach a goto end to the ifBody if else is present */
3455 ifBody = newNode (NULLOP, ifBody,
3457 newAst_VALUE (symbolVal (ifEnd)),
3459 /* put the elseLabel on the else body */
3460 elseBody = createLabel (ifFalse, elseBody);
3461 /* out the end at the end of the body */
3462 elseBody = newNode (NULLOP,
3464 createLabel (ifEnd, NULL));
3468 ifBody = newNode (NULLOP, ifBody,
3469 createLabel (ifFalse, NULL));
3471 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3472 if (IS_IFX (condAst))
3475 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3477 return newNode (NULLOP, ifTree,
3478 newNode (NULLOP, ifBody, elseBody));
3482 /*-----------------------------------------------------------------*/
3483 /* createDo - creates parse tree for do */
3486 /* _docontinue_n: */
3487 /* condition_expression +-> trueLabel -> _dobody_n */
3489 /* +-> falseLabel-> _dobreak_n */
3491 /*-----------------------------------------------------------------*/
3493 createDo (symbol * trueLabel, symbol * continueLabel,
3494 symbol * falseLabel, ast * condAst, ast * doBody)
3499 /* if the body does not exist then it is simple */
3502 condAst = backPatchLabels (condAst, continueLabel, NULL);
3503 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3504 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3505 doTree->trueLabel = continueLabel;
3506 doTree->falseLabel = NULL;
3510 /* otherwise we have a body */
3511 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3513 /* attach the body label to the top */
3514 doBody = createLabel (trueLabel, doBody);
3515 /* attach the continue label to end of body */
3516 doBody = newNode (NULLOP, doBody,
3517 createLabel (continueLabel, NULL));
3519 /* now put the break label at the end */
3520 if (IS_IFX (condAst))
3523 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3525 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3527 /* putting it together */
3528 return newNode (NULLOP, doBody, doTree);
3531 /*-----------------------------------------------------------------*/
3532 /* createFor - creates parse tree for 'for' statement */
3535 /* condExpr +-> trueLabel -> _forbody_n */
3537 /* +-> falseLabel-> _forbreak_n */
3540 /* _forcontinue_n: */
3542 /* goto _forcond_n ; */
3544 /*-----------------------------------------------------------------*/
3546 createFor (symbol * trueLabel, symbol * continueLabel,
3547 symbol * falseLabel, symbol * condLabel,
3548 ast * initExpr, ast * condExpr, ast * loopExpr,
3553 /* if loopexpression not present then we can generate it */
3554 /* the same way as a while */
3556 return newNode (NULLOP, initExpr,
3557 createWhile (trueLabel, continueLabel,
3558 falseLabel, condExpr, forBody));
3559 /* vanilla for statement */
3560 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3562 if (condExpr && !IS_IFX (condExpr))
3563 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3566 /* attach condition label to condition */
3567 condExpr = createLabel (condLabel, condExpr);
3569 /* attach body label to body */
3570 forBody = createLabel (trueLabel, forBody);
3572 /* attach continue to forLoop expression & attach */
3573 /* goto the forcond @ and of loopExpression */
3574 loopExpr = createLabel (continueLabel,
3578 newAst_VALUE (symbolVal (condLabel)),
3580 /* now start putting them together */
3581 forTree = newNode (NULLOP, initExpr, condExpr);
3582 forTree = newNode (NULLOP, forTree, forBody);
3583 forTree = newNode (NULLOP, forTree, loopExpr);
3584 /* finally add the break label */
3585 forTree = newNode (NULLOP, forTree,
3586 createLabel (falseLabel, NULL));
3590 /*-----------------------------------------------------------------*/
3591 /* createWhile - creates parse tree for while statement */
3592 /* the while statement will be created as follows */
3594 /* _while_continue_n: */
3595 /* condition_expression +-> trueLabel -> _while_boby_n */
3597 /* +-> falseLabel -> _while_break_n */
3598 /* _while_body_n: */
3600 /* goto _while_continue_n */
3601 /* _while_break_n: */
3602 /*-----------------------------------------------------------------*/
3604 createWhile (symbol * trueLabel, symbol * continueLabel,
3605 symbol * falseLabel, ast * condExpr, ast * whileBody)
3609 /* put the continue label */
3610 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3611 condExpr = createLabel (continueLabel, condExpr);
3612 condExpr->lineno = 0;
3614 /* put the body label in front of the body */
3615 whileBody = createLabel (trueLabel, whileBody);
3616 whileBody->lineno = 0;
3617 /* put a jump to continue at the end of the body */
3618 /* and put break label at the end of the body */
3619 whileBody = newNode (NULLOP,
3622 newAst_VALUE (symbolVal (continueLabel)),
3623 createLabel (falseLabel, NULL)));
3625 /* put it all together */
3626 if (IS_IFX (condExpr))
3627 whileTree = condExpr;
3630 whileTree = newNode (IFX, condExpr, NULL);
3631 /* put the true & false labels in place */
3632 whileTree->trueLabel = trueLabel;
3633 whileTree->falseLabel = falseLabel;
3636 return newNode (NULLOP, whileTree, whileBody);
3639 /*-----------------------------------------------------------------*/
3640 /* optimizeGetHbit - get highest order bit of the expression */
3641 /*-----------------------------------------------------------------*/
3643 optimizeGetHbit (ast * tree)
3646 /* if this is not a bit and */
3647 if (!IS_BITAND (tree))
3650 /* will look for tree of the form
3651 ( expr >> ((sizeof expr) -1) ) & 1 */
3652 if (!IS_AST_LIT_VALUE (tree->right))
3655 if (AST_LIT_VALUE (tree->right) != 1)
3658 if (!IS_RIGHT_OP (tree->left))
3661 if (!IS_AST_LIT_VALUE (tree->left->right))
3664 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3665 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3668 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3672 /*-----------------------------------------------------------------*/
3673 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3674 /*-----------------------------------------------------------------*/
3676 optimizeRRCRLC (ast * root)
3678 /* will look for trees of the form
3679 (?expr << 1) | (?expr >> 7) or
3680 (?expr >> 7) | (?expr << 1) will make that
3681 into a RLC : operation ..
3683 (?expr >> 1) | (?expr << 7) or
3684 (?expr << 7) | (?expr >> 1) will make that
3685 into a RRC operation
3686 note : by 7 I mean (number of bits required to hold the
3688 /* if the root operations is not a | operation the not */
3689 if (!IS_BITOR (root))
3692 /* I have to think of a better way to match patterns this sucks */
3693 /* that aside let start looking for the first case : I use a the
3694 negative check a lot to improve the efficiency */
3695 /* (?expr << 1) | (?expr >> 7) */
3696 if (IS_LEFT_OP (root->left) &&
3697 IS_RIGHT_OP (root->right))
3700 if (!SPEC_USIGN (TETYPE (root->left->left)))
3703 if (!IS_AST_LIT_VALUE (root->left->right) ||
3704 !IS_AST_LIT_VALUE (root->right->right))
3707 /* make sure it is the same expression */
3708 if (!isAstEqual (root->left->left,
3712 if (AST_LIT_VALUE (root->left->right) != 1)
3715 if (AST_LIT_VALUE (root->right->right) !=
3716 (getSize (TTYPE (root->left->left)) * 8 - 1))
3719 /* whew got the first case : create the AST */
3720 return newNode (RLC, root->left->left, NULL);
3724 /* check for second case */
3725 /* (?expr >> 7) | (?expr << 1) */
3726 if (IS_LEFT_OP (root->right) &&
3727 IS_RIGHT_OP (root->left))
3730 if (!SPEC_USIGN (TETYPE (root->left->left)))
3733 if (!IS_AST_LIT_VALUE (root->left->right) ||
3734 !IS_AST_LIT_VALUE (root->right->right))
3737 /* make sure it is the same symbol */
3738 if (!isAstEqual (root->left->left,
3742 if (AST_LIT_VALUE (root->right->right) != 1)
3745 if (AST_LIT_VALUE (root->left->right) !=
3746 (getSize (TTYPE (root->left->left)) * 8 - 1))
3749 /* whew got the first case : create the AST */
3750 return newNode (RLC, root->left->left, NULL);
3755 /* third case for RRC */
3756 /* (?symbol >> 1) | (?symbol << 7) */
3757 if (IS_LEFT_OP (root->right) &&
3758 IS_RIGHT_OP (root->left))
3761 if (!SPEC_USIGN (TETYPE (root->left->left)))
3764 if (!IS_AST_LIT_VALUE (root->left->right) ||
3765 !IS_AST_LIT_VALUE (root->right->right))
3768 /* make sure it is the same symbol */
3769 if (!isAstEqual (root->left->left,
3773 if (AST_LIT_VALUE (root->left->right) != 1)
3776 if (AST_LIT_VALUE (root->right->right) !=
3777 (getSize (TTYPE (root->left->left)) * 8 - 1))
3780 /* whew got the first case : create the AST */
3781 return newNode (RRC, root->left->left, NULL);
3785 /* fourth and last case for now */
3786 /* (?symbol << 7) | (?symbol >> 1) */
3787 if (IS_RIGHT_OP (root->right) &&
3788 IS_LEFT_OP (root->left))
3791 if (!SPEC_USIGN (TETYPE (root->left->left)))
3794 if (!IS_AST_LIT_VALUE (root->left->right) ||
3795 !IS_AST_LIT_VALUE (root->right->right))
3798 /* make sure it is the same symbol */
3799 if (!isAstEqual (root->left->left,
3803 if (AST_LIT_VALUE (root->right->right) != 1)
3806 if (AST_LIT_VALUE (root->left->right) !=
3807 (getSize (TTYPE (root->left->left)) * 8 - 1))
3810 /* whew got the first case : create the AST */
3811 return newNode (RRC, root->left->left, NULL);
3815 /* not found return root */
3819 /*-----------------------------------------------------------------*/
3820 /* optimizeCompare - otimizes compares for bit variables */
3821 /*-----------------------------------------------------------------*/
3823 optimizeCompare (ast * root)
3825 ast *optExpr = NULL;
3828 unsigned int litValue;
3830 /* if nothing then return nothing */
3834 /* if not a compare op then do leaves */
3835 if (!IS_COMPARE_OP (root))
3837 root->left = optimizeCompare (root->left);
3838 root->right = optimizeCompare (root->right);
3842 /* if left & right are the same then depending
3843 of the operation do */
3844 if (isAstEqual (root->left, root->right))
3846 switch (root->opval.op)
3851 optExpr = newAst_VALUE (constVal ("0"));
3856 optExpr = newAst_VALUE (constVal ("1"));
3860 return decorateType (optExpr);
3863 vleft = (root->left->type == EX_VALUE ?
3864 root->left->opval.val : NULL);
3866 vright = (root->right->type == EX_VALUE ?
3867 root->right->opval.val : NULL);
3869 /* if left is a BITVAR in BITSPACE */
3870 /* and right is a LITERAL then opt- */
3871 /* imize else do nothing */
3872 if (vleft && vright &&
3873 IS_BITVAR (vleft->etype) &&
3874 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3875 IS_LITERAL (vright->etype))
3878 /* if right side > 1 then comparison may never succeed */
3879 if ((litValue = (int) floatFromVal (vright)) > 1)
3881 werror (W_BAD_COMPARE);
3887 switch (root->opval.op)
3889 case '>': /* bit value greater than 1 cannot be */
3890 werror (W_BAD_COMPARE);
3894 case '<': /* bit value < 1 means 0 */
3896 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3899 case LE_OP: /* bit value <= 1 means no check */
3900 optExpr = newAst_VALUE (vright);
3903 case GE_OP: /* bit value >= 1 means only check for = */
3905 optExpr = newAst_VALUE (vleft);
3910 { /* literal is zero */
3911 switch (root->opval.op)
3913 case '<': /* bit value < 0 cannot be */
3914 werror (W_BAD_COMPARE);
3918 case '>': /* bit value > 0 means 1 */
3920 optExpr = newAst_VALUE (vleft);
3923 case LE_OP: /* bit value <= 0 means no check */
3924 case GE_OP: /* bit value >= 0 means no check */
3925 werror (W_BAD_COMPARE);
3929 case EQ_OP: /* bit == 0 means ! of bit */
3930 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3934 return decorateType (resolveSymbols (optExpr));
3935 } /* end-of-if of BITVAR */
3940 /*-----------------------------------------------------------------*/
3941 /* addSymToBlock : adds the symbol to the first block we find */
3942 /*-----------------------------------------------------------------*/
3944 addSymToBlock (symbol * sym, ast * tree)
3946 /* reached end of tree or a leaf */
3947 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3951 if (IS_AST_OP (tree) &&
3952 tree->opval.op == BLOCK)
3955 symbol *lsym = copySymbol (sym);
3957 lsym->next = AST_VALUES (tree, sym);
3958 AST_VALUES (tree, sym) = lsym;
3962 addSymToBlock (sym, tree->left);
3963 addSymToBlock (sym, tree->right);
3966 /*-----------------------------------------------------------------*/
3967 /* processRegParms - do processing for register parameters */
3968 /*-----------------------------------------------------------------*/
3970 processRegParms (value * args, ast * body)
3974 if (IS_REGPARM (args->etype))
3975 addSymToBlock (args->sym, body);
3980 /*-----------------------------------------------------------------*/
3981 /* resetParmKey - resets the operandkeys for the symbols */
3982 /*-----------------------------------------------------------------*/
3983 DEFSETFUNC (resetParmKey)
3994 /*-----------------------------------------------------------------*/
3995 /* createFunction - This is the key node that calls the iCode for */
3996 /* generating the code for a function. Note code */
3997 /* is generated function by function, later when */
3998 /* add inter-procedural analysis this will change */
3999 /*-----------------------------------------------------------------*/
4001 createFunction (symbol * name, ast * body)
4007 iCode *piCode = NULL;
4009 /* if check function return 0 then some problem */
4010 if (checkFunction (name) == 0)
4013 /* create a dummy block if none exists */
4015 body = newNode (BLOCK, NULL, NULL);
4019 /* check if the function name already in the symbol table */
4020 if ((csym = findSym (SymbolTab, NULL, name->name)))
4023 /* special case for compiler defined functions
4024 we need to add the name to the publics list : this
4025 actually means we are now compiling the compiler
4029 addSet (&publics, name);
4035 allocVariables (name);
4037 name->lastLine = yylineno;
4039 processFuncArgs (currFunc, 0);
4041 /* set the stack pointer */
4042 /* PENDING: check this for the mcs51 */
4043 stackPtr = -port->stack.direction * port->stack.call_overhead;
4044 if (IS_ISR (name->etype))
4045 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4046 if (IS_RENT (name->etype) || options.stackAuto)
4047 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4049 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4051 fetype = getSpec (name->type); /* get the specifier for the function */
4052 /* if this is a reentrant function then */
4053 if (IS_RENT (fetype))
4056 allocParms (name->args); /* allocate the parameters */
4058 /* do processing for parameters that are passed in registers */
4059 processRegParms (name->args, body);
4061 /* set the stack pointer */
4065 /* allocate & autoinit the block variables */
4066 processBlockVars (body, &stack, ALLOCATE);
4068 /* save the stack information */
4069 if (options.useXstack)
4070 name->xstack = SPEC_STAK (fetype) = stack;
4072 name->stack = SPEC_STAK (fetype) = stack;
4074 /* name needs to be mangled */
4075 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4077 body = resolveSymbols (body); /* resolve the symbols */
4078 body = decorateType (body); /* propagateType & do semantic checks */
4080 ex = newAst_VALUE (symbolVal (name)); /* create name */
4081 ex = newNode (FUNCTION, ex, body);
4082 ex->values.args = name->args;
4086 werror (E_FUNC_NO_CODE, name->name);
4090 /* create the node & generate intermediate code */
4092 codeOutFile = code->oFile;
4093 piCode = iCodeFromAst (ex);
4097 werror (E_FUNC_NO_CODE, name->name);
4101 eBBlockFromiCode (piCode);
4103 /* if there are any statics then do them */
4106 GcurMemmap = statsg;
4107 codeOutFile = statsg->oFile;
4108 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4114 /* dealloc the block variables */
4115 processBlockVars (body, &stack, DEALLOCATE);
4116 /* deallocate paramaters */
4117 deallocParms (name->args);
4119 if (IS_RENT (fetype))
4122 /* we are done freeup memory & cleanup */
4127 addSet (&operKeyReset, name);
4128 applyToSet (operKeyReset, resetParmKey);
4130 if (options.debug && !options.nodebug)
4131 cdbStructBlock (1, cdbFile);
4133 cleanUpLevel (LabelTab, 0);
4134 cleanUpBlock (StructTab, 1);
4135 cleanUpBlock (TypedefTab, 1);
4137 xstack->syms = NULL;
4138 istack->syms = NULL;