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 *);
63 printTypeChain (tree->ftype, stdout);
68 /*-----------------------------------------------------------------*/
69 /* newAst - creates a fresh node for an expression tree */
70 /*-----------------------------------------------------------------*/
73 newAst (int type, void *op)
76 static int oldLineno = 0;
78 Safe_calloc (1, ex, sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
87 /* depending on the type */
91 ex->opval.val = (value *) op;
94 ex->opval.op = (long) op;
97 ex->opval.lnk = (sym_link *) op;
100 ex->opval.stmnt = (unsigned) op;
108 newAst_ (unsigned type)
111 static int oldLineno = 0;
113 ex = Safe_calloc (1, sizeof (ast));
116 ex->lineno = (noLineno ? oldLineno : yylineno);
117 ex->filename = currFname;
118 ex->level = NestLevel;
119 ex->block = currBlockno;
120 ex->initMode = inInitMode;
125 newAst_VALUE (value * val)
127 ast *ex = newAst_ (EX_VALUE);
133 newAst_OP (unsigned op)
135 ast *ex = newAst_ (EX_OP);
141 newAst_LINK (sym_link * val)
143 ast *ex = newAst_ (EX_LINK);
149 newAst_STMNT (unsigned val)
151 ast *ex = newAst_ (EX_STMNT);
152 ex->opval.stmnt = val;
156 /*-----------------------------------------------------------------*/
157 /* newNode - creates a new node */
158 /*-----------------------------------------------------------------*/
160 newNode (long op, ast * left, ast * right)
171 /*-----------------------------------------------------------------*/
172 /* newIfxNode - creates a new Ifx Node */
173 /*-----------------------------------------------------------------*/
175 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
179 /* if this is a literal then we already know the result */
180 if (condAst->etype && IS_LITERAL (condAst->etype))
183 /* then depending on the expression value */
184 if (floatFromVal (condAst->opval.val))
185 ifxNode = newNode (GOTO,
186 newAst_VALUE (symbolVal (trueLabel)),
189 ifxNode = newNode (GOTO,
190 newAst_VALUE (symbolVal (falseLabel)),
195 ifxNode = newNode (IFX, condAst, NULL);
196 ifxNode->trueLabel = trueLabel;
197 ifxNode->falseLabel = falseLabel;
203 /*-----------------------------------------------------------------*/
204 /* copyAstValues - copies value portion of ast if needed */
205 /*-----------------------------------------------------------------*/
207 copyAstValues (ast * dest, ast * src)
209 switch (src->opval.op)
212 dest->values.sym = copySymbolChain (src->values.sym);
216 dest->values.switchVals.swVals =
217 copyValue (src->values.switchVals.swVals);
218 dest->values.switchVals.swDefault =
219 src->values.switchVals.swDefault;
220 dest->values.switchVals.swNum =
221 src->values.switchVals.swNum;
225 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
226 strcpy (dest->values.inlineasm, src->values.inlineasm);
229 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
230 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
231 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
232 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
233 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
234 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
235 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
240 /*-----------------------------------------------------------------*/
241 /* copyAst - makes a copy of a given astession */
242 /*-----------------------------------------------------------------*/
251 dest = Safe_calloc (1, sizeof (ast));
253 dest->type = src->type;
254 dest->lineno = src->lineno;
255 dest->level = src->level;
256 dest->funcName = src->funcName;
257 dest->argSym = src->argSym;
259 /* if this is a leaf */
261 if (src->type == EX_VALUE)
263 dest->opval.val = copyValue (src->opval.val);
268 if (src->type == EX_LINK)
270 dest->opval.lnk = copyLinkChain (src->opval.lnk);
274 dest->opval.op = src->opval.op;
276 /* if this is a node that has special values */
277 copyAstValues (dest, src);
280 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
282 dest->trueLabel = copySymbol (src->trueLabel);
283 dest->falseLabel = copySymbol (src->falseLabel);
284 dest->left = copyAst (src->left);
285 dest->right = copyAst (src->right);
291 /*-----------------------------------------------------------------*/
292 /* hasSEFcalls - returns TRUE if tree has a function call */
293 /*-----------------------------------------------------------------*/
295 hasSEFcalls (ast * tree)
300 if (tree->type == EX_OP &&
301 (tree->opval.op == CALL ||
302 tree->opval.op == PCALL ||
303 tree->opval.op == '=' ||
304 tree->opval.op == INC_OP ||
305 tree->opval.op == DEC_OP))
308 return (hasSEFcalls (tree->left) |
309 hasSEFcalls (tree->right));
312 /*-----------------------------------------------------------------*/
313 /* isAstEqual - compares two asts & returns 1 if they are equal */
314 /*-----------------------------------------------------------------*/
316 isAstEqual (ast * t1, ast * t2)
325 if (t1->type != t2->type)
331 if (t1->opval.op != t2->opval.op)
333 return (isAstEqual (t1->left, t2->left) &&
334 isAstEqual (t1->right, t2->right));
338 if (t1->opval.val->sym)
340 if (!t2->opval.val->sym)
343 return isSymbolEqual (t1->opval.val->sym,
348 if (t2->opval.val->sym)
351 return (floatFromVal (t1->opval.val) ==
352 floatFromVal (t2->opval.val));
356 /* only compare these two types */
364 /*-----------------------------------------------------------------*/
365 /* resolveSymbols - resolve symbols from the symbol table */
366 /*-----------------------------------------------------------------*/
368 resolveSymbols (ast * tree)
370 /* walk the entire tree and check for values */
371 /* with symbols if we find one then replace */
372 /* symbol with that from the symbol table */
378 /* if not block & function */
379 if (tree->type == EX_OP &&
380 (tree->opval.op != FUNCTION &&
381 tree->opval.op != BLOCK &&
382 tree->opval.op != NULLOP))
384 filename = tree->filename;
385 lineno = tree->lineno;
388 /* make sure we resolve the true & false labels for ifx */
389 if (tree->type == EX_OP && tree->opval.op == IFX)
395 if ((csym = findSym (LabelTab, tree->trueLabel,
396 tree->trueLabel->name)))
397 tree->trueLabel = csym;
399 werror (E_LABEL_UNDEF, tree->trueLabel->name);
402 if (tree->falseLabel)
404 if ((csym = findSym (LabelTab,
406 tree->falseLabel->name)))
407 tree->falseLabel = csym;
409 werror (E_LABEL_UNDEF, tree->falseLabel->name);
414 /* if this is a label resolve it from the labelTab */
415 if (IS_AST_VALUE (tree) &&
416 tree->opval.val->sym &&
417 tree->opval.val->sym->islbl)
420 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
421 tree->opval.val->sym->name);
424 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
426 tree->opval.val->sym = csym;
428 goto resolveChildren;
431 /* do only for leafs */
432 if (IS_AST_VALUE (tree) &&
433 tree->opval.val->sym &&
434 !tree->opval.val->sym->implicit)
437 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
439 /* if found in the symbol table & they r not the same */
440 if (csym && tree->opval.val->sym != csym)
442 tree->opval.val->sym = csym;
443 tree->opval.val->type = csym->type;
444 tree->opval.val->etype = csym->etype;
447 /* if not found in the symbol table */
448 /* mark it as undefined assume it is */
449 /* an integer in data space */
450 if (!csym && !tree->opval.val->sym->implicit)
453 /* if this is a function name then */
454 /* mark it as returning an int */
457 tree->opval.val->sym->type = newLink ();
458 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
459 tree->opval.val->sym->type->next =
460 tree->opval.val->sym->etype = newIntLink ();
461 tree->opval.val->etype = tree->opval.val->etype;
462 tree->opval.val->type = tree->opval.val->sym->type;
463 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
467 tree->opval.val->sym->undefined = 1;
468 tree->opval.val->type =
469 tree->opval.val->etype = newIntLink ();
470 tree->opval.val->sym->type =
471 tree->opval.val->sym->etype = newIntLink ();
477 resolveSymbols (tree->left);
478 resolveSymbols (tree->right);
483 /*-----------------------------------------------------------------*/
484 /* setAstLineno - walks a ast tree & sets the line number */
485 /*-----------------------------------------------------------------*/
487 setAstLineno (ast * tree, int lineno)
492 tree->lineno = lineno;
493 setAstLineno (tree->left, lineno);
494 setAstLineno (tree->right, lineno);
499 /* this functions seems to be superfluous?! kmh */
501 /*-----------------------------------------------------------------*/
502 /* resolveFromTable - will return the symbal table value */
503 /*-----------------------------------------------------------------*/
505 resolveFromTable (value * val)
512 csym = findSymWithLevel (SymbolTab, val->sym);
514 /* if found in the symbol table & they r not the same */
515 if (csym && val->sym != csym &&
516 csym->level == val->sym->level &&
522 val->type = csym->type;
523 val->etype = csym->etype;
530 /*-----------------------------------------------------------------*/
531 /* funcOfType :- function of type with name */
532 /*-----------------------------------------------------------------*/
534 funcOfType (char *name, sym_link * type, sym_link * argType,
539 /* create the symbol */
540 sym = newSymbol (name, 0);
542 /* if arguments required */
547 args = sym->args = newValue ();
551 argStack += getSize (type);
552 args->type = copyLinkChain (argType);
553 args->etype = getSpec (args->type);
556 args = args->next = newValue ();
560 /* setup return value */
561 sym->type = newLink ();
562 DCL_TYPE (sym->type) = FUNCTION;
563 sym->type->next = copyLinkChain (type);
564 sym->etype = getSpec (sym->type);
565 SPEC_RENT (sym->etype) = rent;
570 sym->argStack = (rent ? argStack : 0);
571 allocVariables (sym);
576 /*-----------------------------------------------------------------*/
577 /* reverseParms - will reverse a parameter tree */
578 /*-----------------------------------------------------------------*/
580 reverseParms (ast * ptree)
586 /* top down if we find a nonParm tree then quit */
587 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
590 ptree->left = ptree->right;
591 ptree->right = ttree;
592 reverseParms (ptree->left);
593 reverseParms (ptree->right);
599 /*-----------------------------------------------------------------*/
600 /* processParms - makes sure the parameters are okay and do some */
601 /* processing with them */
602 /*-----------------------------------------------------------------*/
604 processParms (ast * func,
610 sym_link *fetype = func->etype;
612 /* if none of them exist */
613 if (!defParm && !actParm)
616 /* if the function is being called via a pointer & */
617 /* it has not been defined a reentrant then we cannot */
618 /* have parameters */
619 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
621 werror (E_NONRENT_ARGS);
625 /* if defined parameters ended but actual parameters */
626 /* exist and this is not defined as a variable arg */
627 /* also check if statckAuto option is specified */
628 if ((!defParm) && actParm && (!func->hasVargs) &&
629 !options.stackAuto && !IS_RENT (fetype))
631 werror (E_TOO_MANY_PARMS);
635 /* if defined parameters present but no actual parameters */
636 if (defParm && !actParm)
638 werror (E_TOO_FEW_PARMS);
642 /* If this is a varargs function... */
643 if (!defParm && actParm && func->hasVargs)
647 if (IS_CAST_OP (actParm)
648 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
650 /* Parameter was explicitly typecast; don't touch it. */
654 /* If it's a small integer, upcast to int. */
655 if (IS_INTEGRAL (actParm->ftype)
656 && getSize (actParm->ftype) < (unsigned) INTSIZE)
658 newType = newAst_LINK (INTTYPE);
661 if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
663 newType = newAst_LINK (copyLinkChain (actParm->ftype));
664 DCL_TYPE (newType->opval.lnk) = GPOINTER;
667 if (IS_AGGREGATE (actParm->ftype))
669 newType = newAst_LINK (copyLinkChain (actParm->ftype));
670 DCL_TYPE (newType->opval.lnk) = GPOINTER;
675 /* cast required; change this op to a cast. */
676 ast *parmCopy = resolveSymbols (copyAst (actParm));
678 actParm->type = EX_OP;
679 actParm->opval.op = CAST;
680 actParm->left = newType;
681 actParm->right = parmCopy;
682 decorateType (actParm);
684 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
686 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
687 processParms (func, NULL, actParm->right, parmNumber, rightmost));
692 /* if defined parameters ended but actual has not & */
694 if (!defParm && actParm &&
695 (options.stackAuto || IS_RENT (fetype)))
698 resolveSymbols (actParm);
699 /* if this is a PARAM node then match left & right */
700 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
702 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
703 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
707 /* If we have found a value node by following only right-hand links,
708 * then we know that there are no more values after us.
710 * Therefore, if there are more defined parameters, the caller didn't
713 if (rightmost && defParm->next)
715 werror (E_TOO_FEW_PARMS);
720 /* the parameter type must be at least castable */
721 if (checkType (defParm->type, actParm->ftype) == 0)
723 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
724 werror (E_CONTINUE, "defined type ");
725 printTypeChain (defParm->type, stderr);
726 fprintf (stderr, "\n");
727 werror (E_CONTINUE, "actual type ");
728 printTypeChain (actParm->ftype, stderr);
729 fprintf (stderr, "\n");
732 /* if the parameter is castable then add the cast */
733 if (checkType (defParm->type, actParm->ftype) < 0)
735 ast *pTree = resolveSymbols (copyAst (actParm));
737 /* now change the current one to a cast */
738 actParm->type = EX_OP;
739 actParm->opval.op = CAST;
740 actParm->left = newAst_LINK (defParm->type);
741 actParm->right = pTree;
742 actParm->etype = defParm->etype;
743 actParm->ftype = defParm->type;
746 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
748 actParm->argSym = defParm->sym;
749 /* make a copy and change the regparm type to the defined parm */
750 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
751 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
755 /*-----------------------------------------------------------------*/
756 /* createIvalType - generates ival for basic types */
757 /*-----------------------------------------------------------------*/
759 createIvalType (ast * sym, sym_link * type, initList * ilist)
763 /* if initList is deep */
764 if (ilist->type == INIT_DEEP)
765 ilist = ilist->init.deep;
767 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
768 return decorateType (newNode ('=', sym, iExpr));
771 /*-----------------------------------------------------------------*/
772 /* createIvalStruct - generates initial value for structures */
773 /*-----------------------------------------------------------------*/
775 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
781 sflds = SPEC_STRUCT (type)->fields;
782 if (ilist->type != INIT_DEEP)
784 werror (E_INIT_STRUCT, "");
788 iloop = ilist->init.deep;
790 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
794 /* if we have come to end */
798 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
799 lAst = decorateType (resolveSymbols (lAst));
800 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
806 /*-----------------------------------------------------------------*/
807 /* createIvalArray - generates code for array initialization */
808 /*-----------------------------------------------------------------*/
810 createIvalArray (ast * sym, sym_link * type, initList * ilist)
814 int lcnt = 0, size = 0;
816 /* take care of the special case */
817 /* array of characters can be init */
819 if (IS_CHAR (type->next))
820 if ((rast = createIvalCharPtr (sym,
822 decorateType (resolveSymbols (list2expr (ilist))))))
824 return decorateType (resolveSymbols (rast));
826 /* not the special case */
827 if (ilist->type != INIT_DEEP)
829 werror (E_INIT_STRUCT, "");
833 iloop = ilist->init.deep;
834 lcnt = DCL_ELEM (type);
841 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
842 aSym = decorateType (resolveSymbols (aSym));
843 rast = createIval (aSym, type->next, iloop, rast);
844 iloop = (iloop ? iloop->next : NULL);
847 /* if not array limits given & we */
848 /* are out of initialisers then */
849 if (!DCL_ELEM (type) && !iloop)
852 /* no of elements given and we */
853 /* have generated for all of them */
858 /* if we have not been given a size */
859 if (!DCL_ELEM (type))
860 DCL_ELEM (type) = size;
862 return decorateType (resolveSymbols (rast));
866 /*-----------------------------------------------------------------*/
867 /* createIvalCharPtr - generates initial values for char pointers */
868 /*-----------------------------------------------------------------*/
870 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
874 /* if this is a pointer & right is a literal array then */
875 /* just assignment will do */
876 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
877 SPEC_SCLS (iexpr->etype) == S_CODE)
878 && IS_ARRAY (iexpr->ftype)))
879 return newNode ('=', sym, iexpr);
881 /* left side is an array so we have to assign each */
883 if ((IS_LITERAL (iexpr->etype) ||
884 SPEC_SCLS (iexpr->etype) == S_CODE)
885 && IS_ARRAY (iexpr->ftype))
888 /* for each character generate an assignment */
889 /* to the array element */
890 char *s = SPEC_CVAL (iexpr->etype).v_char;
895 rast = newNode (NULLOP,
899 newAst_VALUE (valueFromLit ((float) i))),
900 newAst_VALUE (valueFromLit (*s))));
904 rast = newNode (NULLOP,
908 newAst_VALUE (valueFromLit ((float) i))),
909 newAst_VALUE (valueFromLit (*s))));
910 return decorateType (resolveSymbols (rast));
916 /*-----------------------------------------------------------------*/
917 /* createIvalPtr - generates initial value for pointers */
918 /*-----------------------------------------------------------------*/
920 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
926 if (ilist->type == INIT_DEEP)
927 ilist = ilist->init.deep;
929 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
931 /* if character pointer */
932 if (IS_CHAR (type->next))
933 if ((rast = createIvalCharPtr (sym, type, iexpr)))
936 return newNode ('=', sym, iexpr);
939 /*-----------------------------------------------------------------*/
940 /* createIval - generates code for initial value */
941 /*-----------------------------------------------------------------*/
943 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
950 /* if structure then */
951 if (IS_STRUCT (type))
952 rast = createIvalStruct (sym, type, ilist);
954 /* if this is a pointer */
956 rast = createIvalPtr (sym, type, ilist);
958 /* if this is an array */
960 rast = createIvalArray (sym, type, ilist);
962 /* if type is SPECIFIER */
964 rast = createIvalType (sym, type, ilist);
966 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
968 return decorateType (resolveSymbols (rast));
971 /*-----------------------------------------------------------------*/
972 /* initAggregates - initialises aggregate variables with initv */
973 /*-----------------------------------------------------------------*/
975 initAggregates (symbol * sym, initList * ival, ast * wid)
977 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
980 /*-----------------------------------------------------------------*/
981 /* gatherAutoInit - creates assignment expressions for initial */
983 /*-----------------------------------------------------------------*/
985 gatherAutoInit (symbol * autoChain)
992 for (sym = autoChain; sym; sym = sym->next)
995 /* resolve the symbols in the ival */
997 resolveIvalSym (sym->ival);
999 /* if this is a static variable & has an */
1000 /* initial value the code needs to be lifted */
1001 /* here to the main portion since they can be */
1002 /* initialised only once at the start */
1003 if (IS_STATIC (sym->etype) && sym->ival &&
1004 SPEC_SCLS (sym->etype) != S_CODE)
1008 /* insert the symbol into the symbol table */
1009 /* with level = 0 & name = rname */
1010 newSym = copySymbol (sym);
1011 addSym (SymbolTab, newSym, newSym->name, 0, 0);
1013 /* now lift the code to main */
1014 if (IS_AGGREGATE (sym->type))
1015 work = initAggregates (sym, sym->ival, NULL);
1017 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1018 list2expr (sym->ival));
1020 setAstLineno (work, sym->lineDef);
1024 staticAutos = newNode (NULLOP, staticAutos, work);
1031 /* if there is an initial value */
1032 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1034 if (IS_AGGREGATE (sym->type))
1035 work = initAggregates (sym, sym->ival, NULL);
1037 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1038 list2expr (sym->ival));
1040 setAstLineno (work, sym->lineDef);
1043 init = newNode (NULLOP, init, work);
1052 /*-----------------------------------------------------------------*/
1053 /* stringToSymbol - creates a symbol from a literal string */
1054 /*-----------------------------------------------------------------*/
1056 stringToSymbol (value * val)
1058 char name[SDCC_NAME_MAX + 1];
1059 static int charLbl = 0;
1062 sprintf (name, "_str_%d", charLbl++);
1063 sym = newSymbol (name, 0); /* make it @ level 0 */
1064 strcpy (sym->rname, name);
1066 /* copy the type from the value passed */
1067 sym->type = copyLinkChain (val->type);
1068 sym->etype = getSpec (sym->type);
1069 /* change to storage class & output class */
1070 SPEC_SCLS (sym->etype) = S_CODE;
1071 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1072 SPEC_STAT (sym->etype) = 1;
1073 /* make the level & block = 0 */
1074 sym->block = sym->level = 0;
1076 /* create an ival */
1077 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1082 allocVariables (sym);
1085 return symbolVal (sym);
1089 /*-----------------------------------------------------------------*/
1090 /* processBlockVars - will go thru the ast looking for block if */
1091 /* a block is found then will allocate the syms */
1092 /* will also gather the auto inits present */
1093 /*-----------------------------------------------------------------*/
1095 processBlockVars (ast * tree, int *stack, int action)
1100 /* if this is a block */
1101 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1105 if (action == ALLOCATE)
1107 autoInit = gatherAutoInit (tree->values.sym);
1108 *stack += allocVariables (tree->values.sym);
1110 /* if there are auto inits then do them */
1112 tree->left = newNode (NULLOP, autoInit, tree->left);
1114 else /* action is deallocate */
1115 deallocLocal (tree->values.sym);
1118 processBlockVars (tree->left, stack, action);
1119 processBlockVars (tree->right, stack, action);
1123 /*-----------------------------------------------------------------*/
1124 /* constExprValue - returns the value of a constant expression */
1125 /*-----------------------------------------------------------------*/
1127 constExprValue (ast * cexpr, int check)
1129 cexpr = decorateType (resolveSymbols (cexpr));
1131 /* if this is not a constant then */
1132 if (!IS_LITERAL (cexpr->ftype))
1134 /* then check if this is a literal array
1136 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1137 SPEC_CVAL (cexpr->etype).v_char &&
1138 IS_ARRAY (cexpr->ftype))
1140 value *val = valFromType (cexpr->ftype);
1141 SPEC_SCLS (val->etype) = S_LITERAL;
1142 val->sym = cexpr->opval.val->sym;
1143 val->sym->type = copyLinkChain (cexpr->ftype);
1144 val->sym->etype = getSpec (val->sym->type);
1145 strcpy (val->name, cexpr->opval.val->sym->rname);
1149 /* if we are casting a literal value then */
1150 if (IS_AST_OP (cexpr) &&
1151 cexpr->opval.op == CAST &&
1152 IS_LITERAL (cexpr->left->ftype))
1153 return valCastLiteral (cexpr->ftype,
1154 floatFromVal (cexpr->left->opval.val));
1156 if (IS_AST_VALUE (cexpr))
1157 return cexpr->opval.val;
1160 werror (E_CONST_EXPECTED, "found expression");
1165 /* return the value */
1166 return cexpr->opval.val;
1170 /*-----------------------------------------------------------------*/
1171 /* isLabelInAst - will return true if a given label is found */
1172 /*-----------------------------------------------------------------*/
1174 isLabelInAst (symbol * label, ast * tree)
1176 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1179 if (IS_AST_OP (tree) &&
1180 tree->opval.op == LABEL &&
1181 isSymbolEqual (AST_SYMBOL (tree->left), label))
1184 return isLabelInAst (label, tree->right) &&
1185 isLabelInAst (label, tree->left);
1189 /*-----------------------------------------------------------------*/
1190 /* isLoopCountable - return true if the loop count can be determi- */
1191 /* -ned at compile time . */
1192 /*-----------------------------------------------------------------*/
1194 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1195 symbol ** sym, ast ** init, ast ** end)
1198 /* the loop is considered countable if the following
1199 conditions are true :-
1201 a) initExpr :- <sym> = <const>
1202 b) condExpr :- <sym> < <const1>
1203 c) loopExpr :- <sym> ++
1206 /* first check the initExpr */
1207 if (IS_AST_OP (initExpr) &&
1208 initExpr->opval.op == '=' && /* is assignment */
1209 IS_AST_SYM_VALUE (initExpr->left))
1210 { /* left is a symbol */
1212 *sym = AST_SYMBOL (initExpr->left);
1213 *init = initExpr->right;
1218 /* for now the symbol has to be of
1220 if (!IS_INTEGRAL ((*sym)->type))
1223 /* now check condExpr */
1224 if (IS_AST_OP (condExpr))
1227 switch (condExpr->opval.op)
1230 if (IS_AST_SYM_VALUE (condExpr->left) &&
1231 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1232 IS_AST_LIT_VALUE (condExpr->right))
1234 *end = condExpr->right;
1240 if (IS_AST_OP (condExpr->left) &&
1241 condExpr->left->opval.op == '>' &&
1242 IS_AST_LIT_VALUE (condExpr->left->right) &&
1243 IS_AST_SYM_VALUE (condExpr->left->left) &&
1244 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1247 *end = newNode ('+', condExpr->left->right,
1248 newAst_VALUE (constVal ("1")));
1259 /* check loop expression is of the form <sym>++ */
1260 if (!IS_AST_OP (loopExpr))
1263 /* check if <sym> ++ */
1264 if (loopExpr->opval.op == INC_OP)
1270 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1271 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1278 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1279 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1287 if (loopExpr->opval.op == ADD_ASSIGN)
1290 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1291 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1292 IS_AST_LIT_VALUE (loopExpr->right) &&
1293 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1301 /*-----------------------------------------------------------------*/
1302 /* astHasVolatile - returns true if ast contains any volatile */
1303 /*-----------------------------------------------------------------*/
1305 astHasVolatile (ast * tree)
1310 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1313 if (IS_AST_OP (tree))
1314 return astHasVolatile (tree->left) ||
1315 astHasVolatile (tree->right);
1320 /*-----------------------------------------------------------------*/
1321 /* astHasPointer - return true if the ast contains any ptr variable */
1322 /*-----------------------------------------------------------------*/
1324 astHasPointer (ast * tree)
1329 if (IS_AST_LINK (tree))
1332 /* if we hit an array expression then check
1333 only the left side */
1334 if (IS_AST_OP (tree) && tree->opval.op == '[')
1335 return astHasPointer (tree->left);
1337 if (IS_AST_VALUE (tree))
1338 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1340 return astHasPointer (tree->left) ||
1341 astHasPointer (tree->right);
1345 /*-----------------------------------------------------------------*/
1346 /* astHasSymbol - return true if the ast has the given symbol */
1347 /*-----------------------------------------------------------------*/
1349 astHasSymbol (ast * tree, symbol * sym)
1351 if (!tree || IS_AST_LINK (tree))
1354 if (IS_AST_VALUE (tree))
1356 if (IS_AST_SYM_VALUE (tree))
1357 return isSymbolEqual (AST_SYMBOL (tree), sym);
1362 return astHasSymbol (tree->left, sym) ||
1363 astHasSymbol (tree->right, sym);
1366 /*-----------------------------------------------------------------*/
1367 /* isConformingBody - the loop body has to conform to a set of rules */
1368 /* for the loop to be considered reversible read on for rules */
1369 /*-----------------------------------------------------------------*/
1371 isConformingBody (ast * pbody, symbol * sym, ast * body)
1374 /* we are going to do a pre-order traversal of the
1375 tree && check for the following conditions. (essentially
1376 a set of very shallow tests )
1377 a) the sym passed does not participate in
1378 any arithmetic operation
1379 b) There are no function calls
1380 c) all jumps are within the body
1381 d) address of loop control variable not taken
1382 e) if an assignment has a pointer on the
1383 left hand side make sure right does not have
1384 loop control variable */
1386 /* if we reach the end or a leaf then true */
1387 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1391 /* if anything else is "volatile" */
1392 if (IS_VOLATILE (TETYPE (pbody)))
1395 /* we will walk the body in a pre-order traversal for
1397 switch (pbody->opval.op)
1399 /*------------------------------------------------------------------*/
1401 return isConformingBody (pbody->right, sym, body);
1403 /*------------------------------------------------------------------*/
1408 /*------------------------------------------------------------------*/
1409 case INC_OP: /* incerement operator unary so left only */
1412 /* sure we are not sym is not modified */
1414 IS_AST_SYM_VALUE (pbody->left) &&
1415 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1419 IS_AST_SYM_VALUE (pbody->right) &&
1420 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1425 /*------------------------------------------------------------------*/
1427 case '*': /* can be unary : if right is null then unary operation */
1432 /* if right is NULL then unary operation */
1433 /*------------------------------------------------------------------*/
1434 /*----------------------------*/
1436 /*----------------------------*/
1439 if (IS_AST_SYM_VALUE (pbody->left) &&
1440 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1443 return isConformingBody (pbody->left, sym, body);
1447 if (astHasSymbol (pbody->left, sym) ||
1448 astHasSymbol (pbody->right, sym))
1453 /*------------------------------------------------------------------*/
1461 if (IS_AST_SYM_VALUE (pbody->left) &&
1462 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1465 if (IS_AST_SYM_VALUE (pbody->right) &&
1466 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1469 return isConformingBody (pbody->left, sym, body) &&
1470 isConformingBody (pbody->right, sym, body);
1477 if (IS_AST_SYM_VALUE (pbody->left) &&
1478 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1480 return isConformingBody (pbody->left, sym, body);
1482 /*------------------------------------------------------------------*/
1494 case SIZEOF: /* evaluate wihout code generation */
1496 return isConformingBody (pbody->left, sym, body) &&
1497 isConformingBody (pbody->right, sym, body);
1499 /*------------------------------------------------------------------*/
1502 /* if left has a pointer & right has loop
1503 control variable then we cannot */
1504 if (astHasPointer (pbody->left) &&
1505 astHasSymbol (pbody->right, sym))
1507 if (astHasVolatile (pbody->left))
1510 if (IS_AST_SYM_VALUE (pbody->left) &&
1511 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1514 if (astHasVolatile (pbody->left))
1517 return isConformingBody (pbody->left, sym, body) &&
1518 isConformingBody (pbody->right, sym, body);
1529 assert ("Parser should not have generated this\n");
1531 /*------------------------------------------------------------------*/
1532 /*----------------------------*/
1533 /* comma operator */
1534 /*----------------------------*/
1536 return isConformingBody (pbody->left, sym, body) &&
1537 isConformingBody (pbody->right, sym, body);
1539 /*------------------------------------------------------------------*/
1540 /*----------------------------*/
1542 /*----------------------------*/
1546 /*------------------------------------------------------------------*/
1547 /*----------------------------*/
1548 /* return statement */
1549 /*----------------------------*/
1554 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1559 if (astHasSymbol (pbody->left, sym))
1566 return isConformingBody (pbody->left, sym, body) &&
1567 isConformingBody (pbody->right, sym, body);
1573 /*-----------------------------------------------------------------*/
1574 /* isLoopReversible - takes a for loop as input && returns true */
1575 /* if the for loop is reversible. If yes will set the value of */
1576 /* the loop control var & init value & termination value */
1577 /*-----------------------------------------------------------------*/
1579 isLoopReversible (ast * loop, symbol ** loopCntrl,
1580 ast ** init, ast ** end)
1582 /* if option says don't do it then don't */
1583 if (optimize.noLoopReverse)
1585 /* there are several tests to determine this */
1587 /* for loop has to be of the form
1588 for ( <sym> = <const1> ;
1589 [<sym> < <const2>] ;
1590 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1592 if (!isLoopCountable (AST_FOR (loop, initExpr),
1593 AST_FOR (loop, condExpr),
1594 AST_FOR (loop, loopExpr),
1595 loopCntrl, init, end))
1598 /* now do some serious checking on the body of the loop
1601 return isConformingBody (loop->left, *loopCntrl, loop->left);
1605 /*-----------------------------------------------------------------*/
1606 /* replLoopSym - replace the loop sym by loop sym -1 */
1607 /*-----------------------------------------------------------------*/
1609 replLoopSym (ast * body, symbol * sym)
1612 if (!body || IS_AST_LINK (body))
1615 if (IS_AST_SYM_VALUE (body))
1618 if (isSymbolEqual (AST_SYMBOL (body), sym))
1622 body->opval.op = '-';
1623 body->left = newAst_VALUE (symbolVal (sym));
1624 body->right = newAst_VALUE (constVal ("1"));
1632 replLoopSym (body->left, sym);
1633 replLoopSym (body->right, sym);
1637 /*-----------------------------------------------------------------*/
1638 /* reverseLoop - do the actual loop reversal */
1639 /*-----------------------------------------------------------------*/
1641 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1645 /* create the following tree
1650 if (sym) goto for_continue ;
1653 /* put it together piece by piece */
1654 rloop = newNode (NULLOP,
1655 createIf (newAst_VALUE (symbolVal (sym)),
1657 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1660 newAst_VALUE (symbolVal (sym)),
1663 replLoopSym (loop->left, sym);
1665 rloop = newNode (NULLOP,
1667 newAst_VALUE (symbolVal (sym)),
1668 newNode ('-', end, init)),
1669 createLabel (AST_FOR (loop, continueLabel),
1673 newNode (SUB_ASSIGN,
1674 newAst_VALUE (symbolVal (sym)),
1675 newAst_VALUE (constVal ("1"))),
1678 return decorateType (rloop);
1682 #define DEMAND_INTEGER_PROMOTION
1684 #ifdef DEMAND_INTEGER_PROMOTION
1686 /*-----------------------------------------------------------------*/
1687 /* walk a tree looking for the leaves. Add a typecast to the given */
1688 /* type to each value leaf node. */
1689 /*-----------------------------------------------------------------*/
1691 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1695 /* WTF? We should never get here. */
1699 if (!node->left && !node->right)
1701 /* We're at a leaf; if it's a value, apply the typecast */
1702 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1704 *parentPtr = decorateType (newNode (CAST,
1705 newAst_LINK (copyLinkChain (type)),
1713 pushTypeCastToLeaves (type, node->left, &(node->left));
1717 pushTypeCastToLeaves (type, node->right, &(node->right));
1724 /*-----------------------------------------------------------------*/
1725 /* Given an assignment operation in a tree, determine if the LHS */
1726 /* (the result) has a different (integer) type than the RHS. */
1727 /* If so, walk the RHS and add a typecast to the type of the LHS */
1728 /* to all leaf nodes. */
1729 /*-----------------------------------------------------------------*/
1731 propAsgType (ast * tree)
1733 #ifdef DEMAND_INTEGER_PROMOTION
1734 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1736 /* Nothing to do here... */
1740 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1742 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1749 /*-----------------------------------------------------------------*/
1750 /* decorateType - compute type for this tree also does type cheking */
1751 /* this is done bottom up, since type have to flow upwards */
1752 /* it also does constant folding, and paramater checking */
1753 /*-----------------------------------------------------------------*/
1755 decorateType (ast * tree)
1763 /* if already has type then do nothing */
1764 if (tree->decorated)
1767 tree->decorated = 1;
1769 /* print the line */
1770 /* if not block & function */
1771 if (tree->type == EX_OP &&
1772 (tree->opval.op != FUNCTION &&
1773 tree->opval.op != BLOCK &&
1774 tree->opval.op != NULLOP))
1776 filename = tree->filename;
1777 lineno = tree->lineno;
1780 /* if any child is an error | this one is an error do nothing */
1781 if (tree->isError ||
1782 (tree->left && tree->left->isError) ||
1783 (tree->right && tree->right->isError))
1786 /*------------------------------------------------------------------*/
1787 /*----------------------------*/
1788 /* leaf has been reached */
1789 /*----------------------------*/
1790 /* if this is of type value */
1791 /* just get the type */
1792 if (tree->type == EX_VALUE)
1795 if (IS_LITERAL (tree->opval.val->etype))
1798 /* if this is a character array then declare it */
1799 if (IS_ARRAY (tree->opval.val->type))
1800 tree->opval.val = stringToSymbol (tree->opval.val);
1802 /* otherwise just copy the type information */
1803 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1804 if (funcInChain (tree->opval.val->type))
1806 tree->hasVargs = tree->opval.val->sym->hasVargs;
1807 tree->args = copyValueChain (tree->opval.val->sym->args);
1812 if (tree->opval.val->sym)
1814 /* if the undefined flag is set then give error message */
1815 if (tree->opval.val->sym->undefined)
1817 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1819 TTYPE (tree) = TETYPE (tree) =
1820 tree->opval.val->type = tree->opval.val->sym->type =
1821 tree->opval.val->etype = tree->opval.val->sym->etype =
1822 copyLinkChain (INTTYPE);
1827 /* if impilicit i.e. struct/union member then no type */
1828 if (tree->opval.val->sym->implicit)
1829 TTYPE (tree) = TETYPE (tree) = NULL;
1834 /* else copy the type */
1835 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1837 /* and mark it as referenced */
1838 tree->opval.val->sym->isref = 1;
1839 /* if this is of type function or function pointer */
1840 if (funcInChain (tree->opval.val->type))
1842 tree->hasVargs = tree->opval.val->sym->hasVargs;
1843 tree->args = copyValueChain (tree->opval.val->sym->args);
1853 /* if type link for the case of cast */
1854 if (tree->type == EX_LINK)
1856 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1863 dtl = decorateType (tree->left);
1864 dtr = decorateType (tree->right);
1866 /* this is to take care of situations
1867 when the tree gets rewritten */
1868 if (dtl != tree->left)
1870 if (dtr != tree->right)
1874 /* depending on type of operator do */
1876 switch (tree->opval.op)
1878 /*------------------------------------------------------------------*/
1879 /*----------------------------*/
1881 /*----------------------------*/
1884 /* determine which is the array & which the index */
1885 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1888 ast *tempTree = tree->left;
1889 tree->left = tree->right;
1890 tree->right = tempTree;
1893 /* first check if this is a array or a pointer */
1894 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1896 werror (E_NEED_ARRAY_PTR, "[]");
1897 goto errorTreeReturn;
1900 /* check if the type of the idx */
1901 if (!IS_INTEGRAL (RTYPE (tree)))
1903 werror (E_IDX_NOT_INT);
1904 goto errorTreeReturn;
1907 /* if the left is an rvalue then error */
1910 werror (E_LVALUE_REQUIRED, "array access");
1911 goto errorTreeReturn;
1914 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1917 /*------------------------------------------------------------------*/
1918 /*----------------------------*/
1920 /*----------------------------*/
1922 /* if this is not a structure */
1923 if (!IS_STRUCT (LTYPE (tree)))
1925 werror (E_STRUCT_UNION, ".");
1926 goto errorTreeReturn;
1928 TTYPE (tree) = structElemType (LTYPE (tree),
1929 (tree->right->type == EX_VALUE ?
1930 tree->right->opval.val : NULL), &tree->args);
1931 TETYPE (tree) = getSpec (TTYPE (tree));
1934 /*------------------------------------------------------------------*/
1935 /*----------------------------*/
1936 /* struct/union pointer */
1937 /*----------------------------*/
1939 /* if not pointer to a structure */
1940 if (!IS_PTR (LTYPE (tree)))
1942 werror (E_PTR_REQD);
1943 goto errorTreeReturn;
1946 if (!IS_STRUCT (LTYPE (tree)->next))
1948 werror (E_STRUCT_UNION, "->");
1949 goto errorTreeReturn;
1952 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1953 (tree->right->type == EX_VALUE ?
1954 tree->right->opval.val : NULL), &tree->args);
1955 TETYPE (tree) = getSpec (TTYPE (tree));
1958 /*------------------------------------------------------------------*/
1959 /*----------------------------*/
1960 /* ++/-- operation */
1961 /*----------------------------*/
1962 case INC_OP: /* incerement operator unary so left only */
1965 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1966 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1967 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
1968 werror (E_CODE_WRITE, "++/--");
1977 /*------------------------------------------------------------------*/
1978 /*----------------------------*/
1980 /*----------------------------*/
1981 case '&': /* can be unary */
1982 /* if right is NULL then unary operation */
1983 if (tree->right) /* not an unary operation */
1986 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1988 werror (E_BITWISE_OP);
1989 werror (E_CONTINUE, "left & right types are ");
1990 printTypeChain (LTYPE (tree), stderr);
1991 fprintf (stderr, ",");
1992 printTypeChain (RTYPE (tree), stderr);
1993 fprintf (stderr, "\n");
1994 goto errorTreeReturn;
1997 /* if they are both literal */
1998 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2000 tree->type = EX_VALUE;
2001 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2002 valFromType (RETYPE (tree)), '&');
2004 tree->right = tree->left = NULL;
2005 TETYPE (tree) = tree->opval.val->etype;
2006 TTYPE (tree) = tree->opval.val->type;
2010 /* see if this is a GETHBIT operation if yes
2013 ast *otree = optimizeGetHbit (tree);
2016 return decorateType (otree);
2019 /* if right or left is literal then result of that type */
2020 if (IS_LITERAL (RTYPE (tree)))
2023 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2024 TETYPE (tree) = getSpec (TTYPE (tree));
2025 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2029 if (IS_LITERAL (LTYPE (tree)))
2031 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2032 TETYPE (tree) = getSpec (TTYPE (tree));
2033 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2039 computeType (LTYPE (tree), RTYPE (tree));
2040 TETYPE (tree) = getSpec (TTYPE (tree));
2043 LRVAL (tree) = RRVAL (tree) = 1;
2047 /*------------------------------------------------------------------*/
2048 /*----------------------------*/
2050 /*----------------------------*/
2052 p->class = DECLARATOR;
2053 /* if bit field then error */
2054 if (IS_BITVAR (tree->left->etype))
2056 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2057 goto errorTreeReturn;
2060 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2062 werror (E_ILLEGAL_ADDR, "address of register variable");
2063 goto errorTreeReturn;
2066 if (IS_FUNC (LTYPE (tree)))
2068 werror (E_ILLEGAL_ADDR, "address of function");
2069 goto errorTreeReturn;
2074 werror (E_LVALUE_REQUIRED, "address of");
2075 goto errorTreeReturn;
2077 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2079 DCL_TYPE (p) = CPOINTER;
2080 DCL_PTR_CONST (p) = port->mem.code_ro;
2082 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2083 DCL_TYPE (p) = FPOINTER;
2084 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2085 DCL_TYPE (p) = PPOINTER;
2086 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2087 DCL_TYPE (p) = IPOINTER;
2088 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2089 DCL_TYPE (p) = EEPPOINTER;
2091 DCL_TYPE (p) = POINTER;
2093 if (IS_AST_SYM_VALUE (tree->left))
2095 AST_SYMBOL (tree->left)->addrtaken = 1;
2096 AST_SYMBOL (tree->left)->allocreq = 1;
2099 p->next = LTYPE (tree);
2101 TETYPE (tree) = getSpec (TTYPE (tree));
2102 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2103 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2108 /*------------------------------------------------------------------*/
2109 /*----------------------------*/
2111 /*----------------------------*/
2113 /* if the rewrite succeeds then don't go any furthur */
2115 ast *wtree = optimizeRRCRLC (tree);
2117 return decorateType (wtree);
2119 /*------------------------------------------------------------------*/
2120 /*----------------------------*/
2122 /*----------------------------*/
2124 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2126 werror (E_BITWISE_OP);
2127 werror (E_CONTINUE, "left & right types are ");
2128 printTypeChain (LTYPE (tree), stderr);
2129 fprintf (stderr, ",");
2130 printTypeChain (RTYPE (tree), stderr);
2131 fprintf (stderr, "\n");
2132 goto errorTreeReturn;
2135 /* if they are both literal then */
2136 /* rewrite the tree */
2137 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2139 tree->type = EX_VALUE;
2140 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2141 valFromType (RETYPE (tree)),
2143 tree->right = tree->left = NULL;
2144 TETYPE (tree) = tree->opval.val->etype;
2145 TTYPE (tree) = tree->opval.val->type;
2148 LRVAL (tree) = RRVAL (tree) = 1;
2149 TETYPE (tree) = getSpec (TTYPE (tree) =
2150 computeType (LTYPE (tree),
2153 /*------------------------------------------------------------------*/
2154 /*----------------------------*/
2156 /*----------------------------*/
2158 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2160 werror (E_INVALID_OP, "divide");
2161 goto errorTreeReturn;
2163 /* if they are both literal then */
2164 /* rewrite the tree */
2165 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2167 tree->type = EX_VALUE;
2168 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2169 valFromType (RETYPE (tree)));
2170 tree->right = tree->left = NULL;
2171 TETYPE (tree) = getSpec (TTYPE (tree) =
2172 tree->opval.val->type);
2175 LRVAL (tree) = RRVAL (tree) = 1;
2176 TETYPE (tree) = getSpec (TTYPE (tree) =
2177 computeType (LTYPE (tree),
2181 /*------------------------------------------------------------------*/
2182 /*----------------------------*/
2184 /*----------------------------*/
2186 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2188 werror (E_BITWISE_OP);
2189 werror (E_CONTINUE, "left & right types are ");
2190 printTypeChain (LTYPE (tree), stderr);
2191 fprintf (stderr, ",");
2192 printTypeChain (RTYPE (tree), stderr);
2193 fprintf (stderr, "\n");
2194 goto errorTreeReturn;
2196 /* if they are both literal then */
2197 /* rewrite the tree */
2198 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2200 tree->type = EX_VALUE;
2201 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2202 valFromType (RETYPE (tree)));
2203 tree->right = tree->left = NULL;
2204 TETYPE (tree) = getSpec (TTYPE (tree) =
2205 tree->opval.val->type);
2208 LRVAL (tree) = RRVAL (tree) = 1;
2209 TETYPE (tree) = getSpec (TTYPE (tree) =
2210 computeType (LTYPE (tree),
2214 /*------------------------------------------------------------------*/
2215 /*----------------------------*/
2216 /* address dereference */
2217 /*----------------------------*/
2218 case '*': /* can be unary : if right is null then unary operation */
2221 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2223 werror (E_PTR_REQD);
2224 goto errorTreeReturn;
2229 werror (E_LVALUE_REQUIRED, "pointer deref");
2230 goto errorTreeReturn;
2232 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2233 LTYPE (tree)->next : NULL);
2234 TETYPE (tree) = getSpec (TTYPE (tree));
2235 tree->args = tree->left->args;
2236 tree->hasVargs = tree->left->hasVargs;
2237 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2241 /*------------------------------------------------------------------*/
2242 /*----------------------------*/
2243 /* multiplication */
2244 /*----------------------------*/
2245 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2247 werror (E_INVALID_OP, "multiplication");
2248 goto errorTreeReturn;
2251 /* if they are both literal then */
2252 /* rewrite the tree */
2253 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2255 tree->type = EX_VALUE;
2256 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2257 valFromType (RETYPE (tree)));
2258 tree->right = tree->left = NULL;
2259 TETYPE (tree) = getSpec (TTYPE (tree) =
2260 tree->opval.val->type);
2264 /* if left is a literal exchange left & right */
2265 if (IS_LITERAL (LTYPE (tree)))
2267 ast *tTree = tree->left;
2268 tree->left = tree->right;
2269 tree->right = tTree;
2272 LRVAL (tree) = RRVAL (tree) = 1;
2273 TETYPE (tree) = getSpec (TTYPE (tree) =
2274 computeType (LTYPE (tree),
2278 /*------------------------------------------------------------------*/
2279 /*----------------------------*/
2280 /* unary '+' operator */
2281 /*----------------------------*/
2286 if (!IS_INTEGRAL (LTYPE (tree)))
2288 werror (E_UNARY_OP, '+');
2289 goto errorTreeReturn;
2292 /* if left is a literal then do it */
2293 if (IS_LITERAL (LTYPE (tree)))
2295 tree->type = EX_VALUE;
2296 tree->opval.val = valFromType (LETYPE (tree));
2298 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2302 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2306 /*------------------------------------------------------------------*/
2307 /*----------------------------*/
2309 /*----------------------------*/
2311 /* this is not a unary operation */
2312 /* if both pointers then problem */
2313 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2314 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2316 werror (E_PTR_PLUS_PTR);
2317 goto errorTreeReturn;
2320 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2321 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2323 werror (E_PLUS_INVALID, "+");
2324 goto errorTreeReturn;
2327 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2328 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2330 werror (E_PLUS_INVALID, "+");
2331 goto errorTreeReturn;
2333 /* if they are both literal then */
2334 /* rewrite the tree */
2335 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2337 tree->type = EX_VALUE;
2338 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2339 valFromType (RETYPE (tree)));
2340 tree->right = tree->left = NULL;
2341 TETYPE (tree) = getSpec (TTYPE (tree) =
2342 tree->opval.val->type);
2346 /* if the right is a pointer or left is a literal
2347 xchange left & right */
2348 if (IS_ARRAY (RTYPE (tree)) ||
2349 IS_PTR (RTYPE (tree)) ||
2350 IS_LITERAL (LTYPE (tree)))
2352 ast *tTree = tree->left;
2353 tree->left = tree->right;
2354 tree->right = tTree;
2357 LRVAL (tree) = RRVAL (tree) = 1;
2358 /* if the left is a pointer */
2359 if (IS_PTR (LTYPE (tree)))
2360 TETYPE (tree) = getSpec (TTYPE (tree) =
2363 TETYPE (tree) = getSpec (TTYPE (tree) =
2364 computeType (LTYPE (tree),
2368 /*------------------------------------------------------------------*/
2369 /*----------------------------*/
2371 /*----------------------------*/
2372 case '-': /* can be unary */
2373 /* if right is null then unary */
2377 if (!IS_ARITHMETIC (LTYPE (tree)))
2379 werror (E_UNARY_OP, tree->opval.op);
2380 goto errorTreeReturn;
2383 /* if left is a literal then do it */
2384 if (IS_LITERAL (LTYPE (tree)))
2386 tree->type = EX_VALUE;
2387 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2389 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2390 SPEC_USIGN(TETYPE(tree)) = 0;
2394 TTYPE (tree) = LTYPE (tree);
2398 /*------------------------------------------------------------------*/
2399 /*----------------------------*/
2401 /*----------------------------*/
2403 if (!(IS_PTR (LTYPE (tree)) ||
2404 IS_ARRAY (LTYPE (tree)) ||
2405 IS_ARITHMETIC (LTYPE (tree))))
2407 werror (E_PLUS_INVALID, "-");
2408 goto errorTreeReturn;
2411 if (!(IS_PTR (RTYPE (tree)) ||
2412 IS_ARRAY (RTYPE (tree)) ||
2413 IS_ARITHMETIC (RTYPE (tree))))
2415 werror (E_PLUS_INVALID, "-");
2416 goto errorTreeReturn;
2419 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2420 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2421 IS_INTEGRAL (RTYPE (tree))))
2423 werror (E_PLUS_INVALID, "-");
2424 goto errorTreeReturn;
2427 /* if they are both literal then */
2428 /* rewrite the tree */
2429 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2431 tree->type = EX_VALUE;
2432 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2433 valFromType (RETYPE (tree)));
2434 tree->right = tree->left = NULL;
2435 TETYPE (tree) = getSpec (TTYPE (tree) =
2436 tree->opval.val->type);
2440 /* if the left & right are equal then zero */
2441 if (isAstEqual (tree->left, tree->right))
2443 tree->type = EX_VALUE;
2444 tree->left = tree->right = NULL;
2445 tree->opval.val = constVal ("0");
2446 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2450 /* if both of them are pointers or arrays then */
2451 /* the result is going to be an integer */
2452 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2453 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2454 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2456 /* if only the left is a pointer */
2457 /* then result is a pointer */
2458 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2459 TETYPE (tree) = getSpec (TTYPE (tree) =
2462 TETYPE (tree) = getSpec (TTYPE (tree) =
2463 computeType (LTYPE (tree),
2465 LRVAL (tree) = RRVAL (tree) = 1;
2468 /*------------------------------------------------------------------*/
2469 /*----------------------------*/
2471 /*----------------------------*/
2473 /* can be only integral type */
2474 if (!IS_INTEGRAL (LTYPE (tree)))
2476 werror (E_UNARY_OP, tree->opval.op);
2477 goto errorTreeReturn;
2480 /* if left is a literal then do it */
2481 if (IS_LITERAL (LTYPE (tree)))
2483 tree->type = EX_VALUE;
2484 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2486 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2490 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2493 /*------------------------------------------------------------------*/
2494 /*----------------------------*/
2496 /*----------------------------*/
2498 /* can be pointer */
2499 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2500 !IS_PTR (LTYPE (tree)) &&
2501 !IS_ARRAY (LTYPE (tree)))
2503 werror (E_UNARY_OP, tree->opval.op);
2504 goto errorTreeReturn;
2507 /* if left is a literal then do it */
2508 if (IS_LITERAL (LTYPE (tree)))
2510 tree->type = EX_VALUE;
2511 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2513 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2517 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2520 /*------------------------------------------------------------------*/
2521 /*----------------------------*/
2523 /*----------------------------*/
2526 TTYPE (tree) = LTYPE (tree);
2527 TETYPE (tree) = LETYPE (tree);
2531 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2536 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2538 werror (E_SHIFT_OP_INVALID);
2539 werror (E_CONTINUE, "left & right types are ");
2540 printTypeChain (LTYPE (tree), stderr);
2541 fprintf (stderr, ",");
2542 printTypeChain (RTYPE (tree), stderr);
2543 fprintf (stderr, "\n");
2544 goto errorTreeReturn;
2547 /* if they are both literal then */
2548 /* rewrite the tree */
2549 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2551 tree->type = EX_VALUE;
2552 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2553 valFromType (RETYPE (tree)),
2554 (tree->opval.op == LEFT_OP ? 1 : 0));
2555 tree->right = tree->left = NULL;
2556 TETYPE (tree) = getSpec (TTYPE (tree) =
2557 tree->opval.val->type);
2560 /* if only the right side is a literal & we are
2561 shifting more than size of the left operand then zero */
2562 if (IS_LITERAL (RTYPE (tree)) &&
2563 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2564 (getSize (LTYPE (tree)) * 8))
2566 werror (W_SHIFT_CHANGED,
2567 (tree->opval.op == LEFT_OP ? "left" : "right"));
2568 tree->type = EX_VALUE;
2569 tree->left = tree->right = NULL;
2570 tree->opval.val = constVal ("0");
2571 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2574 LRVAL (tree) = RRVAL (tree) = 1;
2575 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2577 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2581 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2585 /*------------------------------------------------------------------*/
2586 /*----------------------------*/
2588 /*----------------------------*/
2589 case CAST: /* change the type */
2590 /* cannot cast to an aggregate type */
2591 if (IS_AGGREGATE (LTYPE (tree)))
2593 werror (E_CAST_ILLEGAL);
2594 goto errorTreeReturn;
2597 /* if the right is a literal replace the tree */
2598 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2600 tree->type = EX_VALUE;
2602 valCastLiteral (LTYPE (tree),
2603 floatFromVal (valFromType (RETYPE (tree))));
2606 TTYPE (tree) = tree->opval.val->type;
2607 tree->values.literalFromCast = 1;
2611 TTYPE (tree) = LTYPE (tree);
2615 TETYPE (tree) = getSpec (TTYPE (tree));
2619 /*------------------------------------------------------------------*/
2620 /*----------------------------*/
2621 /* logical &&, || */
2622 /*----------------------------*/
2625 /* each must me arithmetic type or be a pointer */
2626 if (!IS_PTR (LTYPE (tree)) &&
2627 !IS_ARRAY (LTYPE (tree)) &&
2628 !IS_INTEGRAL (LTYPE (tree)))
2630 werror (E_COMPARE_OP);
2631 goto errorTreeReturn;
2634 if (!IS_PTR (RTYPE (tree)) &&
2635 !IS_ARRAY (RTYPE (tree)) &&
2636 !IS_INTEGRAL (RTYPE (tree)))
2638 werror (E_COMPARE_OP);
2639 goto errorTreeReturn;
2641 /* if they are both literal then */
2642 /* rewrite the tree */
2643 if (IS_LITERAL (RTYPE (tree)) &&
2644 IS_LITERAL (LTYPE (tree)))
2646 tree->type = EX_VALUE;
2647 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2648 valFromType (RETYPE (tree)),
2650 tree->right = tree->left = NULL;
2651 TETYPE (tree) = getSpec (TTYPE (tree) =
2652 tree->opval.val->type);
2655 LRVAL (tree) = RRVAL (tree) = 1;
2656 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2659 /*------------------------------------------------------------------*/
2660 /*----------------------------*/
2661 /* comparison operators */
2662 /*----------------------------*/
2670 ast *lt = optimizeCompare (tree);
2676 /* if they are pointers they must be castable */
2677 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2679 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2681 werror (E_COMPARE_OP);
2682 fprintf (stderr, "comparing type ");
2683 printTypeChain (LTYPE (tree), stderr);
2684 fprintf (stderr, "to type ");
2685 printTypeChain (RTYPE (tree), stderr);
2686 fprintf (stderr, "\n");
2687 goto errorTreeReturn;
2690 /* else they should be promotable to one another */
2693 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2694 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2696 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2698 werror (E_COMPARE_OP);
2699 fprintf (stderr, "comparing type ");
2700 printTypeChain (LTYPE (tree), stderr);
2701 fprintf (stderr, "to type ");
2702 printTypeChain (RTYPE (tree), stderr);
2703 fprintf (stderr, "\n");
2704 goto errorTreeReturn;
2708 /* if they are both literal then */
2709 /* rewrite the tree */
2710 if (IS_LITERAL (RTYPE (tree)) &&
2711 IS_LITERAL (LTYPE (tree)))
2713 tree->type = EX_VALUE;
2714 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2715 valFromType (RETYPE (tree)),
2717 tree->right = tree->left = NULL;
2718 TETYPE (tree) = getSpec (TTYPE (tree) =
2719 tree->opval.val->type);
2722 LRVAL (tree) = RRVAL (tree) = 1;
2723 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2726 /*------------------------------------------------------------------*/
2727 /*----------------------------*/
2729 /*----------------------------*/
2730 case SIZEOF: /* evaluate wihout code generation */
2731 /* change the type to a integer */
2732 tree->type = EX_VALUE;
2733 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2734 tree->opval.val = constVal (buffer);
2735 tree->right = tree->left = NULL;
2736 TETYPE (tree) = getSpec (TTYPE (tree) =
2737 tree->opval.val->type);
2740 /*------------------------------------------------------------------*/
2741 /*----------------------------*/
2742 /* conditional operator '?' */
2743 /*----------------------------*/
2745 /* the type is one on the left */
2746 TTYPE (tree) = LTYPE (tree);
2747 TETYPE (tree) = getSpec (TTYPE (tree));
2751 /* if they don't match we have a problem */
2752 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2754 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2755 goto errorTreeReturn;
2758 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2759 TETYPE (tree) = getSpec (TTYPE (tree));
2763 /*------------------------------------------------------------------*/
2764 /*----------------------------*/
2765 /* assignment operators */
2766 /*----------------------------*/
2769 /* for these it must be both must be integral */
2770 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2771 !IS_ARITHMETIC (RTYPE (tree)))
2773 werror (E_OPS_INTEGRAL);
2774 goto errorTreeReturn;
2777 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2779 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2780 werror (E_CODE_WRITE, " ");
2784 werror (E_LVALUE_REQUIRED, "*= or /=");
2785 goto errorTreeReturn;
2798 /* for these it must be both must be integral */
2799 if (!IS_INTEGRAL (LTYPE (tree)) ||
2800 !IS_INTEGRAL (RTYPE (tree)))
2802 werror (E_OPS_INTEGRAL);
2803 goto errorTreeReturn;
2806 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2808 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2809 werror (E_CODE_WRITE, " ");
2813 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2814 goto errorTreeReturn;
2822 /*------------------------------------------------------------------*/
2823 /*----------------------------*/
2825 /*----------------------------*/
2827 if (!(IS_PTR (LTYPE (tree)) ||
2828 IS_ARITHMETIC (LTYPE (tree))))
2830 werror (E_PLUS_INVALID, "-=");
2831 goto errorTreeReturn;
2834 if (!(IS_PTR (RTYPE (tree)) ||
2835 IS_ARITHMETIC (RTYPE (tree))))
2837 werror (E_PLUS_INVALID, "-=");
2838 goto errorTreeReturn;
2841 TETYPE (tree) = getSpec (TTYPE (tree) =
2842 computeType (LTYPE (tree),
2845 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2846 werror (E_CODE_WRITE, " ");
2850 werror (E_LVALUE_REQUIRED, "-=");
2851 goto errorTreeReturn;
2859 /*------------------------------------------------------------------*/
2860 /*----------------------------*/
2862 /*----------------------------*/
2864 /* this is not a unary operation */
2865 /* if both pointers then problem */
2866 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2868 werror (E_PTR_PLUS_PTR);
2869 goto errorTreeReturn;
2872 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2874 werror (E_PLUS_INVALID, "+=");
2875 goto errorTreeReturn;
2878 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2880 werror (E_PLUS_INVALID, "+=");
2881 goto errorTreeReturn;
2884 TETYPE (tree) = getSpec (TTYPE (tree) =
2885 computeType (LTYPE (tree),
2888 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2889 werror (E_CODE_WRITE, " ");
2893 werror (E_LVALUE_REQUIRED, "+=");
2894 goto errorTreeReturn;
2897 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2898 tree->opval.op = '=';
2904 /*------------------------------------------------------------------*/
2905 /*----------------------------*/
2906 /* straight assignemnt */
2907 /*----------------------------*/
2909 /* cannot be an aggregate */
2910 if (IS_AGGREGATE (LTYPE (tree)))
2912 werror (E_AGGR_ASSIGN);
2913 goto errorTreeReturn;
2916 /* they should either match or be castable */
2917 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2919 werror (E_TYPE_MISMATCH, "assignment", " ");
2920 fprintf (stderr, "type --> '");
2921 printTypeChain (RTYPE (tree), stderr);
2922 fprintf (stderr, "' ");
2923 fprintf (stderr, "assigned to type --> '");
2924 printTypeChain (LTYPE (tree), stderr);
2925 fprintf (stderr, "'\n");
2926 goto errorTreeReturn;
2929 /* if the left side of the tree is of type void
2930 then report error */
2931 if (IS_VOID (LTYPE (tree)))
2933 werror (E_CAST_ZERO);
2934 fprintf (stderr, "type --> '");
2935 printTypeChain (RTYPE (tree), stderr);
2936 fprintf (stderr, "' ");
2937 fprintf (stderr, "assigned to type --> '");
2938 printTypeChain (LTYPE (tree), stderr);
2939 fprintf (stderr, "'\n");
2942 /* extra checks for pointer types */
2943 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2944 !IS_GENPTR (LTYPE (tree)))
2946 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2947 werror (W_PTR_ASSIGN);
2950 TETYPE (tree) = getSpec (TTYPE (tree) =
2954 if (!tree->initMode ) {
2955 if (IS_CONSTANT (LETYPE (tree))) {
2956 werror (E_CODE_WRITE, " ");
2961 werror (E_LVALUE_REQUIRED, "=");
2962 goto errorTreeReturn;
2969 /*------------------------------------------------------------------*/
2970 /*----------------------------*/
2971 /* comma operator */
2972 /*----------------------------*/
2974 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
2977 /*------------------------------------------------------------------*/
2978 /*----------------------------*/
2980 /*----------------------------*/
2984 if (processParms (tree->left,
2986 tree->right, &parmNumber, TRUE))
2987 goto errorTreeReturn;
2989 if (options.stackAuto || IS_RENT (LETYPE (tree)))
2991 tree->left->args = reverseVal (tree->left->args);
2992 reverseParms (tree->right);
2995 tree->args = tree->left->args;
2996 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
2999 /*------------------------------------------------------------------*/
3000 /*----------------------------*/
3001 /* return statement */
3002 /*----------------------------*/
3007 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3009 werror (E_RETURN_MISMATCH);
3010 goto errorTreeReturn;
3013 if (IS_VOID (currFunc->type->next)
3015 !IS_VOID (RTYPE (tree)))
3017 werror (E_FUNC_VOID);
3018 goto errorTreeReturn;
3021 /* if there is going to be a casing required then add it */
3022 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3024 #if 0 && defined DEMAND_INTEGER_PROMOTION
3025 if (IS_INTEGRAL (currFunc->type->next))
3027 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3033 decorateType (newNode (CAST,
3034 newAst_LINK (copyLinkChain (currFunc->type->next)),
3044 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3046 werror (E_VOID_FUNC, currFunc->name);
3047 goto errorTreeReturn;
3050 TTYPE (tree) = TETYPE (tree) = NULL;
3053 /*------------------------------------------------------------------*/
3054 /*----------------------------*/
3055 /* switch statement */
3056 /*----------------------------*/
3058 /* the switch value must be an integer */
3059 if (!IS_INTEGRAL (LTYPE (tree)))
3061 werror (E_SWITCH_NON_INTEGER);
3062 goto errorTreeReturn;
3065 TTYPE (tree) = TETYPE (tree) = NULL;
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3071 /*----------------------------*/
3073 tree->left = backPatchLabels (tree->left,
3076 TTYPE (tree) = TETYPE (tree) = NULL;
3079 /*------------------------------------------------------------------*/
3080 /*----------------------------*/
3082 /*----------------------------*/
3085 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3086 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3087 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3089 /* if the for loop is reversible then
3090 reverse it otherwise do what we normally
3096 if (isLoopReversible (tree, &sym, &init, &end))
3097 return reverseLoop (tree, sym, init, end);
3099 return decorateType (createFor (AST_FOR (tree, trueLabel),
3100 AST_FOR (tree, continueLabel),
3101 AST_FOR (tree, falseLabel),
3102 AST_FOR (tree, condLabel),
3103 AST_FOR (tree, initExpr),
3104 AST_FOR (tree, condExpr),
3105 AST_FOR (tree, loopExpr),
3109 TTYPE (tree) = TETYPE (tree) = NULL;
3113 /* some error found this tree will be killed */
3115 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3116 tree->opval.op = NULLOP;
3122 /*-----------------------------------------------------------------*/
3123 /* sizeofOp - processes size of operation */
3124 /*-----------------------------------------------------------------*/
3126 sizeofOp (sym_link * type)
3130 /* get the size and convert it to character */
3131 sprintf (buff, "%d", getSize (type));
3133 /* now convert into value */
3134 return constVal (buff);
3138 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3139 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3140 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3141 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3142 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3143 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3144 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3146 /*-----------------------------------------------------------------*/
3147 /* backPatchLabels - change and or not operators to flow control */
3148 /*-----------------------------------------------------------------*/
3150 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3156 if (!(IS_ANDORNOT (tree)))
3159 /* if this an and */
3162 static int localLbl = 0;
3165 sprintf (buffer, "_and_%d", localLbl++);
3166 localLabel = newSymbol (buffer, NestLevel);
3168 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3170 /* if left is already a IFX then just change the if true label in that */
3171 if (!IS_IFX (tree->left))
3172 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3174 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3175 /* right is a IFX then just join */
3176 if (IS_IFX (tree->right))
3177 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3179 tree->right = createLabel (localLabel, tree->right);
3180 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3182 return newNode (NULLOP, tree->left, tree->right);
3185 /* if this is an or operation */
3188 static int localLbl = 0;
3191 sprintf (buffer, "_or_%d", localLbl++);
3192 localLabel = newSymbol (buffer, NestLevel);
3194 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3196 /* if left is already a IFX then just change the if true label in that */
3197 if (!IS_IFX (tree->left))
3198 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3200 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3201 /* right is a IFX then just join */
3202 if (IS_IFX (tree->right))
3203 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3205 tree->right = createLabel (localLabel, tree->right);
3206 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3208 return newNode (NULLOP, tree->left, tree->right);
3214 int wasnot = IS_NOT (tree->left);
3215 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3217 /* if the left is already a IFX */
3218 if (!IS_IFX (tree->left))
3219 tree->left = newNode (IFX, tree->left, NULL);
3223 tree->left->trueLabel = trueLabel;
3224 tree->left->falseLabel = falseLabel;
3228 tree->left->trueLabel = falseLabel;
3229 tree->left->falseLabel = trueLabel;
3236 tree->trueLabel = trueLabel;
3237 tree->falseLabel = falseLabel;
3244 /*-----------------------------------------------------------------*/
3245 /* createBlock - create expression tree for block */
3246 /*-----------------------------------------------------------------*/
3248 createBlock (symbol * decl, ast * body)
3252 /* if the block has nothing */
3256 ex = newNode (BLOCK, NULL, body);
3257 ex->values.sym = decl;
3259 ex->right = ex->right;
3265 /*-----------------------------------------------------------------*/
3266 /* createLabel - creates the expression tree for labels */
3267 /*-----------------------------------------------------------------*/
3269 createLabel (symbol * label, ast * stmnt)
3272 char name[SDCC_NAME_MAX + 1];
3275 /* must create fresh symbol if the symbol name */
3276 /* exists in the symbol table, since there can */
3277 /* be a variable with the same name as the labl */
3278 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3279 (csym->level == label->level))
3280 label = newSymbol (label->name, label->level);
3282 /* change the name before putting it in add _ */
3283 sprintf (name, "%s", label->name);
3285 /* put the label in the LabelSymbol table */
3286 /* but first check if a label of the same */
3288 if ((csym = findSym (LabelTab, NULL, name)))
3289 werror (E_DUPLICATE_LABEL, label->name);
3291 addSym (LabelTab, label, name, label->level, 0);
3294 label->key = labelKey++;
3295 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3301 /*-----------------------------------------------------------------*/
3302 /* createCase - generates the parsetree for a case statement */
3303 /*-----------------------------------------------------------------*/
3305 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3307 char caseLbl[SDCC_NAME_MAX + 1];
3311 /* if the switch statement does not exist */
3312 /* then case is out of context */
3315 werror (E_CASE_CONTEXT);
3319 caseVal = decorateType (resolveSymbols (caseVal));
3320 /* if not a constant then error */
3321 if (!IS_LITERAL (caseVal->ftype))
3323 werror (E_CASE_CONSTANT);
3327 /* if not a integer than error */
3328 if (!IS_INTEGRAL (caseVal->ftype))
3330 werror (E_CASE_NON_INTEGER);
3334 /* find the end of the switch values chain */
3335 if (!(val = swStat->values.switchVals.swVals))
3336 swStat->values.switchVals.swVals = caseVal->opval.val;
3339 /* also order the cases according to value */
3341 int cVal = (int) floatFromVal (caseVal->opval.val);
3342 while (val && (int) floatFromVal (val) < cVal)
3348 /* if we reached the end then */
3351 pval->next = caseVal->opval.val;
3355 /* we found a value greater than */
3356 /* the current value we must add this */
3357 /* before the value */
3358 caseVal->opval.val->next = val;
3360 /* if this was the first in chain */
3361 if (swStat->values.switchVals.swVals == val)
3362 swStat->values.switchVals.swVals =
3365 pval->next = caseVal->opval.val;
3370 /* create the case label */
3371 sprintf (caseLbl, "_case_%d_%d",
3372 swStat->values.switchVals.swNum,
3373 (int) floatFromVal (caseVal->opval.val));
3375 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3380 /*-----------------------------------------------------------------*/
3381 /* createDefault - creates the parse tree for the default statement */
3382 /*-----------------------------------------------------------------*/
3384 createDefault (ast * swStat, ast * stmnt)
3386 char defLbl[SDCC_NAME_MAX + 1];
3388 /* if the switch statement does not exist */
3389 /* then case is out of context */
3392 werror (E_CASE_CONTEXT);
3396 /* turn on the default flag */
3397 swStat->values.switchVals.swDefault = 1;
3399 /* create the label */
3400 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3401 return createLabel (newSymbol (defLbl, 0), stmnt);
3404 /*-----------------------------------------------------------------*/
3405 /* createIf - creates the parsetree for the if statement */
3406 /*-----------------------------------------------------------------*/
3408 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3410 static int Lblnum = 0;
3412 symbol *ifTrue, *ifFalse, *ifEnd;
3414 /* if neither exists */
3415 if (!elseBody && !ifBody)
3418 /* create the labels */
3419 sprintf (buffer, "_iffalse_%d", Lblnum);
3420 ifFalse = newSymbol (buffer, NestLevel);
3421 /* if no else body then end == false */
3426 sprintf (buffer, "_ifend_%d", Lblnum);
3427 ifEnd = newSymbol (buffer, NestLevel);
3430 sprintf (buffer, "_iftrue_%d", Lblnum);
3431 ifTrue = newSymbol (buffer, NestLevel);
3435 /* attach the ifTrue label to the top of it body */
3436 ifBody = createLabel (ifTrue, ifBody);
3437 /* attach a goto end to the ifBody if else is present */
3440 ifBody = newNode (NULLOP, ifBody,
3442 newAst_VALUE (symbolVal (ifEnd)),
3444 /* put the elseLabel on the else body */
3445 elseBody = createLabel (ifFalse, elseBody);
3446 /* out the end at the end of the body */
3447 elseBody = newNode (NULLOP,
3449 createLabel (ifEnd, NULL));
3453 ifBody = newNode (NULLOP, ifBody,
3454 createLabel (ifFalse, NULL));
3456 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3457 if (IS_IFX (condAst))
3460 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3462 return newNode (NULLOP, ifTree,
3463 newNode (NULLOP, ifBody, elseBody));
3467 /*-----------------------------------------------------------------*/
3468 /* createDo - creates parse tree for do */
3471 /* _docontinue_n: */
3472 /* condition_expression +-> trueLabel -> _dobody_n */
3474 /* +-> falseLabel-> _dobreak_n */
3476 /*-----------------------------------------------------------------*/
3478 createDo (symbol * trueLabel, symbol * continueLabel,
3479 symbol * falseLabel, ast * condAst, ast * doBody)
3484 /* if the body does not exist then it is simple */
3487 condAst = backPatchLabels (condAst, continueLabel, NULL);
3488 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3489 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3490 doTree->trueLabel = continueLabel;
3491 doTree->falseLabel = NULL;
3495 /* otherwise we have a body */
3496 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3498 /* attach the body label to the top */
3499 doBody = createLabel (trueLabel, doBody);
3500 /* attach the continue label to end of body */
3501 doBody = newNode (NULLOP, doBody,
3502 createLabel (continueLabel, NULL));
3504 /* now put the break label at the end */
3505 if (IS_IFX (condAst))
3508 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3510 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3512 /* putting it together */
3513 return newNode (NULLOP, doBody, doTree);
3516 /*-----------------------------------------------------------------*/
3517 /* createFor - creates parse tree for 'for' statement */
3520 /* condExpr +-> trueLabel -> _forbody_n */
3522 /* +-> falseLabel-> _forbreak_n */
3525 /* _forcontinue_n: */
3527 /* goto _forcond_n ; */
3529 /*-----------------------------------------------------------------*/
3531 createFor (symbol * trueLabel, symbol * continueLabel,
3532 symbol * falseLabel, symbol * condLabel,
3533 ast * initExpr, ast * condExpr, ast * loopExpr,
3538 /* if loopexpression not present then we can generate it */
3539 /* the same way as a while */
3541 return newNode (NULLOP, initExpr,
3542 createWhile (trueLabel, continueLabel,
3543 falseLabel, condExpr, forBody));
3544 /* vanilla for statement */
3545 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3547 if (condExpr && !IS_IFX (condExpr))
3548 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3551 /* attach condition label to condition */
3552 condExpr = createLabel (condLabel, condExpr);
3554 /* attach body label to body */
3555 forBody = createLabel (trueLabel, forBody);
3557 /* attach continue to forLoop expression & attach */
3558 /* goto the forcond @ and of loopExpression */
3559 loopExpr = createLabel (continueLabel,
3563 newAst_VALUE (symbolVal (condLabel)),
3565 /* now start putting them together */
3566 forTree = newNode (NULLOP, initExpr, condExpr);
3567 forTree = newNode (NULLOP, forTree, forBody);
3568 forTree = newNode (NULLOP, forTree, loopExpr);
3569 /* finally add the break label */
3570 forTree = newNode (NULLOP, forTree,
3571 createLabel (falseLabel, NULL));
3575 /*-----------------------------------------------------------------*/
3576 /* createWhile - creates parse tree for while statement */
3577 /* the while statement will be created as follows */
3579 /* _while_continue_n: */
3580 /* condition_expression +-> trueLabel -> _while_boby_n */
3582 /* +-> falseLabel -> _while_break_n */
3583 /* _while_body_n: */
3585 /* goto _while_continue_n */
3586 /* _while_break_n: */
3587 /*-----------------------------------------------------------------*/
3589 createWhile (symbol * trueLabel, symbol * continueLabel,
3590 symbol * falseLabel, ast * condExpr, ast * whileBody)
3594 /* put the continue label */
3595 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3596 condExpr = createLabel (continueLabel, condExpr);
3597 condExpr->lineno = 0;
3599 /* put the body label in front of the body */
3600 whileBody = createLabel (trueLabel, whileBody);
3601 whileBody->lineno = 0;
3602 /* put a jump to continue at the end of the body */
3603 /* and put break label at the end of the body */
3604 whileBody = newNode (NULLOP,
3607 newAst_VALUE (symbolVal (continueLabel)),
3608 createLabel (falseLabel, NULL)));
3610 /* put it all together */
3611 if (IS_IFX (condExpr))
3612 whileTree = condExpr;
3615 whileTree = newNode (IFX, condExpr, NULL);
3616 /* put the true & false labels in place */
3617 whileTree->trueLabel = trueLabel;
3618 whileTree->falseLabel = falseLabel;
3621 return newNode (NULLOP, whileTree, whileBody);
3624 /*-----------------------------------------------------------------*/
3625 /* optimizeGetHbit - get highest order bit of the expression */
3626 /*-----------------------------------------------------------------*/
3628 optimizeGetHbit (ast * tree)
3631 /* if this is not a bit and */
3632 if (!IS_BITAND (tree))
3635 /* will look for tree of the form
3636 ( expr >> ((sizeof expr) -1) ) & 1 */
3637 if (!IS_AST_LIT_VALUE (tree->right))
3640 if (AST_LIT_VALUE (tree->right) != 1)
3643 if (!IS_RIGHT_OP (tree->left))
3646 if (!IS_AST_LIT_VALUE (tree->left->right))
3649 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3650 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3653 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3657 /*-----------------------------------------------------------------*/
3658 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3659 /*-----------------------------------------------------------------*/
3661 optimizeRRCRLC (ast * root)
3663 /* will look for trees of the form
3664 (?expr << 1) | (?expr >> 7) or
3665 (?expr >> 7) | (?expr << 1) will make that
3666 into a RLC : operation ..
3668 (?expr >> 1) | (?expr << 7) or
3669 (?expr << 7) | (?expr >> 1) will make that
3670 into a RRC operation
3671 note : by 7 I mean (number of bits required to hold the
3673 /* if the root operations is not a | operation the not */
3674 if (!IS_BITOR (root))
3677 /* I have to think of a better way to match patterns this sucks */
3678 /* that aside let start looking for the first case : I use a the
3679 negative check a lot to improve the efficiency */
3680 /* (?expr << 1) | (?expr >> 7) */
3681 if (IS_LEFT_OP (root->left) &&
3682 IS_RIGHT_OP (root->right))
3685 if (!SPEC_USIGN (TETYPE (root->left->left)))
3688 if (!IS_AST_LIT_VALUE (root->left->right) ||
3689 !IS_AST_LIT_VALUE (root->right->right))
3692 /* make sure it is the same expression */
3693 if (!isAstEqual (root->left->left,
3697 if (AST_LIT_VALUE (root->left->right) != 1)
3700 if (AST_LIT_VALUE (root->right->right) !=
3701 (getSize (TTYPE (root->left->left)) * 8 - 1))
3704 /* whew got the first case : create the AST */
3705 return newNode (RLC, root->left->left, NULL);
3709 /* check for second case */
3710 /* (?expr >> 7) | (?expr << 1) */
3711 if (IS_LEFT_OP (root->right) &&
3712 IS_RIGHT_OP (root->left))
3715 if (!SPEC_USIGN (TETYPE (root->left->left)))
3718 if (!IS_AST_LIT_VALUE (root->left->right) ||
3719 !IS_AST_LIT_VALUE (root->right->right))
3722 /* make sure it is the same symbol */
3723 if (!isAstEqual (root->left->left,
3727 if (AST_LIT_VALUE (root->right->right) != 1)
3730 if (AST_LIT_VALUE (root->left->right) !=
3731 (getSize (TTYPE (root->left->left)) * 8 - 1))
3734 /* whew got the first case : create the AST */
3735 return newNode (RLC, root->left->left, NULL);
3740 /* third case for RRC */
3741 /* (?symbol >> 1) | (?symbol << 7) */
3742 if (IS_LEFT_OP (root->right) &&
3743 IS_RIGHT_OP (root->left))
3746 if (!SPEC_USIGN (TETYPE (root->left->left)))
3749 if (!IS_AST_LIT_VALUE (root->left->right) ||
3750 !IS_AST_LIT_VALUE (root->right->right))
3753 /* make sure it is the same symbol */
3754 if (!isAstEqual (root->left->left,
3758 if (AST_LIT_VALUE (root->left->right) != 1)
3761 if (AST_LIT_VALUE (root->right->right) !=
3762 (getSize (TTYPE (root->left->left)) * 8 - 1))
3765 /* whew got the first case : create the AST */
3766 return newNode (RRC, root->left->left, NULL);
3770 /* fourth and last case for now */
3771 /* (?symbol << 7) | (?symbol >> 1) */
3772 if (IS_RIGHT_OP (root->right) &&
3773 IS_LEFT_OP (root->left))
3776 if (!SPEC_USIGN (TETYPE (root->left->left)))
3779 if (!IS_AST_LIT_VALUE (root->left->right) ||
3780 !IS_AST_LIT_VALUE (root->right->right))
3783 /* make sure it is the same symbol */
3784 if (!isAstEqual (root->left->left,
3788 if (AST_LIT_VALUE (root->right->right) != 1)
3791 if (AST_LIT_VALUE (root->left->right) !=
3792 (getSize (TTYPE (root->left->left)) * 8 - 1))
3795 /* whew got the first case : create the AST */
3796 return newNode (RRC, root->left->left, NULL);
3800 /* not found return root */
3804 /*-----------------------------------------------------------------*/
3805 /* optimizeCompare - otimizes compares for bit variables */
3806 /*-----------------------------------------------------------------*/
3808 optimizeCompare (ast * root)
3810 ast *optExpr = NULL;
3813 unsigned int litValue;
3815 /* if nothing then return nothing */
3819 /* if not a compare op then do leaves */
3820 if (!IS_COMPARE_OP (root))
3822 root->left = optimizeCompare (root->left);
3823 root->right = optimizeCompare (root->right);
3827 /* if left & right are the same then depending
3828 of the operation do */
3829 if (isAstEqual (root->left, root->right))
3831 switch (root->opval.op)
3836 optExpr = newAst_VALUE (constVal ("0"));
3841 optExpr = newAst_VALUE (constVal ("1"));
3845 return decorateType (optExpr);
3848 vleft = (root->left->type == EX_VALUE ?
3849 root->left->opval.val : NULL);
3851 vright = (root->right->type == EX_VALUE ?
3852 root->right->opval.val : NULL);
3854 /* if left is a BITVAR in BITSPACE */
3855 /* and right is a LITERAL then opt- */
3856 /* imize else do nothing */
3857 if (vleft && vright &&
3858 IS_BITVAR (vleft->etype) &&
3859 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3860 IS_LITERAL (vright->etype))
3863 /* if right side > 1 then comparison may never succeed */
3864 if ((litValue = (int) floatFromVal (vright)) > 1)
3866 werror (W_BAD_COMPARE);
3872 switch (root->opval.op)
3874 case '>': /* bit value greater than 1 cannot be */
3875 werror (W_BAD_COMPARE);
3879 case '<': /* bit value < 1 means 0 */
3881 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3884 case LE_OP: /* bit value <= 1 means no check */
3885 optExpr = newAst_VALUE (vright);
3888 case GE_OP: /* bit value >= 1 means only check for = */
3890 optExpr = newAst_VALUE (vleft);
3895 { /* literal is zero */
3896 switch (root->opval.op)
3898 case '<': /* bit value < 0 cannot be */
3899 werror (W_BAD_COMPARE);
3903 case '>': /* bit value > 0 means 1 */
3905 optExpr = newAst_VALUE (vleft);
3908 case LE_OP: /* bit value <= 0 means no check */
3909 case GE_OP: /* bit value >= 0 means no check */
3910 werror (W_BAD_COMPARE);
3914 case EQ_OP: /* bit == 0 means ! of bit */
3915 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3919 return decorateType (resolveSymbols (optExpr));
3920 } /* end-of-if of BITVAR */
3925 /*-----------------------------------------------------------------*/
3926 /* addSymToBlock : adds the symbol to the first block we find */
3927 /*-----------------------------------------------------------------*/
3929 addSymToBlock (symbol * sym, ast * tree)
3931 /* reached end of tree or a leaf */
3932 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3936 if (IS_AST_OP (tree) &&
3937 tree->opval.op == BLOCK)
3940 symbol *lsym = copySymbol (sym);
3942 lsym->next = AST_VALUES (tree, sym);
3943 AST_VALUES (tree, sym) = lsym;
3947 addSymToBlock (sym, tree->left);
3948 addSymToBlock (sym, tree->right);
3951 /*-----------------------------------------------------------------*/
3952 /* processRegParms - do processing for register parameters */
3953 /*-----------------------------------------------------------------*/
3955 processRegParms (value * args, ast * body)
3959 if (IS_REGPARM (args->etype))
3960 addSymToBlock (args->sym, body);
3965 /*-----------------------------------------------------------------*/
3966 /* resetParmKey - resets the operandkeys for the symbols */
3967 /*-----------------------------------------------------------------*/
3968 DEFSETFUNC (resetParmKey)
3979 /*-----------------------------------------------------------------*/
3980 /* createFunction - This is the key node that calls the iCode for */
3981 /* generating the code for a function. Note code */
3982 /* is generated function by function, later when */
3983 /* add inter-procedural analysis this will change */
3984 /*-----------------------------------------------------------------*/
3986 createFunction (symbol * name, ast * body)
3992 iCode *piCode = NULL;
3994 /* if check function return 0 then some problem */
3995 if (checkFunction (name) == 0)
3998 /* create a dummy block if none exists */
4000 body = newNode (BLOCK, NULL, NULL);
4004 /* check if the function name already in the symbol table */
4005 if ((csym = findSym (SymbolTab, NULL, name->name)))
4008 /* special case for compiler defined functions
4009 we need to add the name to the publics list : this
4010 actually means we are now compiling the compiler
4014 addSet (&publics, name);
4020 allocVariables (name);
4022 name->lastLine = yylineno;
4024 processFuncArgs (currFunc, 0);
4026 /* set the stack pointer */
4027 /* PENDING: check this for the mcs51 */
4028 stackPtr = -port->stack.direction * port->stack.call_overhead;
4029 if (IS_ISR (name->etype))
4030 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4031 if (IS_RENT (name->etype) || options.stackAuto)
4032 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4034 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4036 fetype = getSpec (name->type); /* get the specifier for the function */
4037 /* if this is a reentrant function then */
4038 if (IS_RENT (fetype))
4041 allocParms (name->args); /* allocate the parameters */
4043 /* do processing for parameters that are passed in registers */
4044 processRegParms (name->args, body);
4046 /* set the stack pointer */
4050 /* allocate & autoinit the block variables */
4051 processBlockVars (body, &stack, ALLOCATE);
4053 /* save the stack information */
4054 if (options.useXstack)
4055 name->xstack = SPEC_STAK (fetype) = stack;
4057 name->stack = SPEC_STAK (fetype) = stack;
4059 /* name needs to be mangled */
4060 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4062 body = resolveSymbols (body); /* resolve the symbols */
4063 body = decorateType (body); /* propagateType & do semantic checks */
4065 ex = newAst_VALUE (symbolVal (name)); /* create name */
4066 ex = newNode (FUNCTION, ex, body);
4067 ex->values.args = name->args;
4071 werror (E_FUNC_NO_CODE, name->name);
4075 /* create the node & generate intermediate code */
4076 codeOutFile = code->oFile;
4077 piCode = iCodeFromAst (ex);
4081 werror (E_FUNC_NO_CODE, name->name);
4085 eBBlockFromiCode (piCode);
4087 /* if there are any statics then do them */
4090 codeOutFile = statsg->oFile;
4091 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4097 /* dealloc the block variables */
4098 processBlockVars (body, &stack, DEALLOCATE);
4099 /* deallocate paramaters */
4100 deallocParms (name->args);
4102 if (IS_RENT (fetype))
4105 /* we are done freeup memory & cleanup */
4110 addSet (&operKeyReset, name);
4111 applyToSet (operKeyReset, resetParmKey);
4113 if (options.debug && !options.nodebug)
4114 cdbStructBlock (1, cdbFile);
4116 cleanUpLevel (LabelTab, 0);
4117 cleanUpBlock (StructTab, 1);
4118 cleanUpBlock (TypedefTab, 1);
4120 xstack->syms = NULL;
4121 istack->syms = NULL;