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;
2393 TTYPE (tree) = LTYPE (tree);
2397 /*------------------------------------------------------------------*/
2398 /*----------------------------*/
2400 /*----------------------------*/
2402 if (!(IS_PTR (LTYPE (tree)) ||
2403 IS_ARRAY (LTYPE (tree)) ||
2404 IS_ARITHMETIC (LTYPE (tree))))
2406 werror (E_PLUS_INVALID, "-");
2407 goto errorTreeReturn;
2410 if (!(IS_PTR (RTYPE (tree)) ||
2411 IS_ARRAY (RTYPE (tree)) ||
2412 IS_ARITHMETIC (RTYPE (tree))))
2414 werror (E_PLUS_INVALID, "-");
2415 goto errorTreeReturn;
2418 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2419 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2420 IS_INTEGRAL (RTYPE (tree))))
2422 werror (E_PLUS_INVALID, "-");
2423 goto errorTreeReturn;
2426 /* if they are both literal then */
2427 /* rewrite the tree */
2428 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2430 tree->type = EX_VALUE;
2431 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2432 valFromType (RETYPE (tree)));
2433 tree->right = tree->left = NULL;
2434 TETYPE (tree) = getSpec (TTYPE (tree) =
2435 tree->opval.val->type);
2439 /* if the left & right are equal then zero */
2440 if (isAstEqual (tree->left, tree->right))
2442 tree->type = EX_VALUE;
2443 tree->left = tree->right = NULL;
2444 tree->opval.val = constVal ("0");
2445 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2449 /* if both of them are pointers or arrays then */
2450 /* the result is going to be an integer */
2451 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2452 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2453 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2455 /* if only the left is a pointer */
2456 /* then result is a pointer */
2457 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2458 TETYPE (tree) = getSpec (TTYPE (tree) =
2461 TETYPE (tree) = getSpec (TTYPE (tree) =
2462 computeType (LTYPE (tree),
2464 LRVAL (tree) = RRVAL (tree) = 1;
2467 /*------------------------------------------------------------------*/
2468 /*----------------------------*/
2470 /*----------------------------*/
2472 /* can be only integral type */
2473 if (!IS_INTEGRAL (LTYPE (tree)))
2475 werror (E_UNARY_OP, tree->opval.op);
2476 goto errorTreeReturn;
2479 /* if left is a literal then do it */
2480 if (IS_LITERAL (LTYPE (tree)))
2482 tree->type = EX_VALUE;
2483 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2485 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2489 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2492 /*------------------------------------------------------------------*/
2493 /*----------------------------*/
2495 /*----------------------------*/
2497 /* can be pointer */
2498 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2499 !IS_PTR (LTYPE (tree)) &&
2500 !IS_ARRAY (LTYPE (tree)))
2502 werror (E_UNARY_OP, tree->opval.op);
2503 goto errorTreeReturn;
2506 /* if left is a literal then do it */
2507 if (IS_LITERAL (LTYPE (tree)))
2509 tree->type = EX_VALUE;
2510 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2512 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2516 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2519 /*------------------------------------------------------------------*/
2520 /*----------------------------*/
2522 /*----------------------------*/
2525 TTYPE (tree) = LTYPE (tree);
2526 TETYPE (tree) = LETYPE (tree);
2530 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2535 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2537 werror (E_SHIFT_OP_INVALID);
2538 werror (E_CONTINUE, "left & right types are ");
2539 printTypeChain (LTYPE (tree), stderr);
2540 fprintf (stderr, ",");
2541 printTypeChain (RTYPE (tree), stderr);
2542 fprintf (stderr, "\n");
2543 goto errorTreeReturn;
2546 /* if they are both literal then */
2547 /* rewrite the tree */
2548 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2552 valFromType (RETYPE (tree)),
2553 (tree->opval.op == LEFT_OP ? 1 : 0));
2554 tree->right = tree->left = NULL;
2555 TETYPE (tree) = getSpec (TTYPE (tree) =
2556 tree->opval.val->type);
2559 /* if only the right side is a literal & we are
2560 shifting more than size of the left operand then zero */
2561 if (IS_LITERAL (RTYPE (tree)) &&
2562 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2563 (getSize (LTYPE (tree)) * 8))
2565 werror (W_SHIFT_CHANGED,
2566 (tree->opval.op == LEFT_OP ? "left" : "right"));
2567 tree->type = EX_VALUE;
2568 tree->left = tree->right = NULL;
2569 tree->opval.val = constVal ("0");
2570 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2573 LRVAL (tree) = RRVAL (tree) = 1;
2574 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2576 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2580 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2584 /*------------------------------------------------------------------*/
2585 /*----------------------------*/
2587 /*----------------------------*/
2588 case CAST: /* change the type */
2589 /* cannot cast to an aggregate type */
2590 if (IS_AGGREGATE (LTYPE (tree)))
2592 werror (E_CAST_ILLEGAL);
2593 goto errorTreeReturn;
2596 /* if the right is a literal replace the tree */
2597 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2599 tree->type = EX_VALUE;
2601 valCastLiteral (LTYPE (tree),
2602 floatFromVal (valFromType (RETYPE (tree))));
2605 TTYPE (tree) = tree->opval.val->type;
2606 tree->values.literalFromCast = 1;
2610 TTYPE (tree) = LTYPE (tree);
2614 TETYPE (tree) = getSpec (TTYPE (tree));
2618 /*------------------------------------------------------------------*/
2619 /*----------------------------*/
2620 /* logical &&, || */
2621 /*----------------------------*/
2624 /* each must me arithmetic type or be a pointer */
2625 if (!IS_PTR (LTYPE (tree)) &&
2626 !IS_ARRAY (LTYPE (tree)) &&
2627 !IS_INTEGRAL (LTYPE (tree)))
2629 werror (E_COMPARE_OP);
2630 goto errorTreeReturn;
2633 if (!IS_PTR (RTYPE (tree)) &&
2634 !IS_ARRAY (RTYPE (tree)) &&
2635 !IS_INTEGRAL (RTYPE (tree)))
2637 werror (E_COMPARE_OP);
2638 goto errorTreeReturn;
2640 /* if they are both literal then */
2641 /* rewrite the tree */
2642 if (IS_LITERAL (RTYPE (tree)) &&
2643 IS_LITERAL (LTYPE (tree)))
2645 tree->type = EX_VALUE;
2646 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2647 valFromType (RETYPE (tree)),
2649 tree->right = tree->left = NULL;
2650 TETYPE (tree) = getSpec (TTYPE (tree) =
2651 tree->opval.val->type);
2654 LRVAL (tree) = RRVAL (tree) = 1;
2655 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2658 /*------------------------------------------------------------------*/
2659 /*----------------------------*/
2660 /* comparison operators */
2661 /*----------------------------*/
2669 ast *lt = optimizeCompare (tree);
2675 /* if they are pointers they must be castable */
2676 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2678 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2680 werror (E_COMPARE_OP);
2681 fprintf (stderr, "comparing type ");
2682 printTypeChain (LTYPE (tree), stderr);
2683 fprintf (stderr, "to type ");
2684 printTypeChain (RTYPE (tree), stderr);
2685 fprintf (stderr, "\n");
2686 goto errorTreeReturn;
2689 /* else they should be promotable to one another */
2692 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2693 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2695 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2697 werror (E_COMPARE_OP);
2698 fprintf (stderr, "comparing type ");
2699 printTypeChain (LTYPE (tree), stderr);
2700 fprintf (stderr, "to type ");
2701 printTypeChain (RTYPE (tree), stderr);
2702 fprintf (stderr, "\n");
2703 goto errorTreeReturn;
2707 /* if they are both literal then */
2708 /* rewrite the tree */
2709 if (IS_LITERAL (RTYPE (tree)) &&
2710 IS_LITERAL (LTYPE (tree)))
2712 tree->type = EX_VALUE;
2713 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2714 valFromType (RETYPE (tree)),
2716 tree->right = tree->left = NULL;
2717 TETYPE (tree) = getSpec (TTYPE (tree) =
2718 tree->opval.val->type);
2721 LRVAL (tree) = RRVAL (tree) = 1;
2722 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2725 /*------------------------------------------------------------------*/
2726 /*----------------------------*/
2728 /*----------------------------*/
2729 case SIZEOF: /* evaluate wihout code generation */
2730 /* change the type to a integer */
2731 tree->type = EX_VALUE;
2732 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2733 tree->opval.val = constVal (buffer);
2734 tree->right = tree->left = NULL;
2735 TETYPE (tree) = getSpec (TTYPE (tree) =
2736 tree->opval.val->type);
2739 /*------------------------------------------------------------------*/
2740 /*----------------------------*/
2741 /* conditional operator '?' */
2742 /*----------------------------*/
2744 /* the type is one on the left */
2745 TTYPE (tree) = LTYPE (tree);
2746 TETYPE (tree) = getSpec (TTYPE (tree));
2750 /* if they don't match we have a problem */
2751 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2753 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2754 goto errorTreeReturn;
2757 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2758 TETYPE (tree) = getSpec (TTYPE (tree));
2762 /*------------------------------------------------------------------*/
2763 /*----------------------------*/
2764 /* assignment operators */
2765 /*----------------------------*/
2768 /* for these it must be both must be integral */
2769 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2770 !IS_ARITHMETIC (RTYPE (tree)))
2772 werror (E_OPS_INTEGRAL);
2773 goto errorTreeReturn;
2776 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2778 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2779 werror (E_CODE_WRITE, " ");
2783 werror (E_LVALUE_REQUIRED, "*= or /=");
2784 goto errorTreeReturn;
2797 /* for these it must be both must be integral */
2798 if (!IS_INTEGRAL (LTYPE (tree)) ||
2799 !IS_INTEGRAL (RTYPE (tree)))
2801 werror (E_OPS_INTEGRAL);
2802 goto errorTreeReturn;
2805 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2807 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2808 werror (E_CODE_WRITE, " ");
2812 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2813 goto errorTreeReturn;
2821 /*------------------------------------------------------------------*/
2822 /*----------------------------*/
2824 /*----------------------------*/
2826 if (!(IS_PTR (LTYPE (tree)) ||
2827 IS_ARITHMETIC (LTYPE (tree))))
2829 werror (E_PLUS_INVALID, "-=");
2830 goto errorTreeReturn;
2833 if (!(IS_PTR (RTYPE (tree)) ||
2834 IS_ARITHMETIC (RTYPE (tree))))
2836 werror (E_PLUS_INVALID, "-=");
2837 goto errorTreeReturn;
2840 TETYPE (tree) = getSpec (TTYPE (tree) =
2841 computeType (LTYPE (tree),
2844 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2845 werror (E_CODE_WRITE, " ");
2849 werror (E_LVALUE_REQUIRED, "-=");
2850 goto errorTreeReturn;
2858 /*------------------------------------------------------------------*/
2859 /*----------------------------*/
2861 /*----------------------------*/
2863 /* this is not a unary operation */
2864 /* if both pointers then problem */
2865 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2867 werror (E_PTR_PLUS_PTR);
2868 goto errorTreeReturn;
2871 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2873 werror (E_PLUS_INVALID, "+=");
2874 goto errorTreeReturn;
2877 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2879 werror (E_PLUS_INVALID, "+=");
2880 goto errorTreeReturn;
2883 TETYPE (tree) = getSpec (TTYPE (tree) =
2884 computeType (LTYPE (tree),
2887 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2888 werror (E_CODE_WRITE, " ");
2892 werror (E_LVALUE_REQUIRED, "+=");
2893 goto errorTreeReturn;
2896 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2897 tree->opval.op = '=';
2903 /*------------------------------------------------------------------*/
2904 /*----------------------------*/
2905 /* straight assignemnt */
2906 /*----------------------------*/
2908 /* cannot be an aggregate */
2909 if (IS_AGGREGATE (LTYPE (tree)))
2911 werror (E_AGGR_ASSIGN);
2912 goto errorTreeReturn;
2915 /* they should either match or be castable */
2916 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2918 werror (E_TYPE_MISMATCH, "assignment", " ");
2919 fprintf (stderr, "type --> '");
2920 printTypeChain (RTYPE (tree), stderr);
2921 fprintf (stderr, "' ");
2922 fprintf (stderr, "assigned to type --> '");
2923 printTypeChain (LTYPE (tree), stderr);
2924 fprintf (stderr, "'\n");
2925 goto errorTreeReturn;
2928 /* if the left side of the tree is of type void
2929 then report error */
2930 if (IS_VOID (LTYPE (tree)))
2932 werror (E_CAST_ZERO);
2933 fprintf (stderr, "type --> '");
2934 printTypeChain (RTYPE (tree), stderr);
2935 fprintf (stderr, "' ");
2936 fprintf (stderr, "assigned to type --> '");
2937 printTypeChain (LTYPE (tree), stderr);
2938 fprintf (stderr, "'\n");
2941 /* extra checks for pointer types */
2942 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2943 !IS_GENPTR (LTYPE (tree)))
2945 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2946 werror (W_PTR_ASSIGN);
2949 TETYPE (tree) = getSpec (TTYPE (tree) =
2953 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2954 werror (E_CODE_WRITE, " ");
2958 werror (E_LVALUE_REQUIRED, "=");
2959 goto errorTreeReturn;
2966 /*------------------------------------------------------------------*/
2967 /*----------------------------*/
2968 /* comma operator */
2969 /*----------------------------*/
2971 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
2974 /*------------------------------------------------------------------*/
2975 /*----------------------------*/
2977 /*----------------------------*/
2981 if (processParms (tree->left,
2983 tree->right, &parmNumber, TRUE))
2984 goto errorTreeReturn;
2986 if (options.stackAuto || IS_RENT (LETYPE (tree)))
2988 tree->left->args = reverseVal (tree->left->args);
2989 reverseParms (tree->right);
2992 tree->args = tree->left->args;
2993 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
2996 /*------------------------------------------------------------------*/
2997 /*----------------------------*/
2998 /* return statement */
2999 /*----------------------------*/
3004 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3006 werror (E_RETURN_MISMATCH);
3007 goto errorTreeReturn;
3010 if (IS_VOID (currFunc->type->next)
3012 !IS_VOID (RTYPE (tree)))
3014 werror (E_FUNC_VOID);
3015 goto errorTreeReturn;
3018 /* if there is going to be a casing required then add it */
3019 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3021 #if 0 && defined DEMAND_INTEGER_PROMOTION
3022 if (IS_INTEGRAL (currFunc->type->next))
3024 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3030 decorateType (newNode (CAST,
3031 newAst_LINK (copyLinkChain (currFunc->type->next)),
3041 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3043 werror (E_VOID_FUNC, currFunc->name);
3044 goto errorTreeReturn;
3047 TTYPE (tree) = TETYPE (tree) = NULL;
3050 /*------------------------------------------------------------------*/
3051 /*----------------------------*/
3052 /* switch statement */
3053 /*----------------------------*/
3055 /* the switch value must be an integer */
3056 if (!IS_INTEGRAL (LTYPE (tree)))
3058 werror (E_SWITCH_NON_INTEGER);
3059 goto errorTreeReturn;
3062 TTYPE (tree) = TETYPE (tree) = NULL;
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3068 /*----------------------------*/
3070 tree->left = backPatchLabels (tree->left,
3073 TTYPE (tree) = TETYPE (tree) = NULL;
3076 /*------------------------------------------------------------------*/
3077 /*----------------------------*/
3079 /*----------------------------*/
3082 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3083 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3084 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3086 /* if the for loop is reversible then
3087 reverse it otherwise do what we normally
3093 if (isLoopReversible (tree, &sym, &init, &end))
3094 return reverseLoop (tree, sym, init, end);
3096 return decorateType (createFor (AST_FOR (tree, trueLabel),
3097 AST_FOR (tree, continueLabel),
3098 AST_FOR (tree, falseLabel),
3099 AST_FOR (tree, condLabel),
3100 AST_FOR (tree, initExpr),
3101 AST_FOR (tree, condExpr),
3102 AST_FOR (tree, loopExpr),
3106 TTYPE (tree) = TETYPE (tree) = NULL;
3110 /* some error found this tree will be killed */
3112 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3113 tree->opval.op = NULLOP;
3119 /*-----------------------------------------------------------------*/
3120 /* sizeofOp - processes size of operation */
3121 /*-----------------------------------------------------------------*/
3123 sizeofOp (sym_link * type)
3127 /* get the size and convert it to character */
3128 sprintf (buff, "%d", getSize (type));
3130 /* now convert into value */
3131 return constVal (buff);
3135 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3136 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3137 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3138 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3139 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3140 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3141 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3143 /*-----------------------------------------------------------------*/
3144 /* backPatchLabels - change and or not operators to flow control */
3145 /*-----------------------------------------------------------------*/
3147 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3153 if (!(IS_ANDORNOT (tree)))
3156 /* if this an and */
3159 static int localLbl = 0;
3162 sprintf (buffer, "_and_%d", localLbl++);
3163 localLabel = newSymbol (buffer, NestLevel);
3165 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3167 /* if left is already a IFX then just change the if true label in that */
3168 if (!IS_IFX (tree->left))
3169 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3171 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3172 /* right is a IFX then just join */
3173 if (IS_IFX (tree->right))
3174 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3176 tree->right = createLabel (localLabel, tree->right);
3177 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3179 return newNode (NULLOP, tree->left, tree->right);
3182 /* if this is an or operation */
3185 static int localLbl = 0;
3188 sprintf (buffer, "_or_%d", localLbl++);
3189 localLabel = newSymbol (buffer, NestLevel);
3191 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3193 /* if left is already a IFX then just change the if true label in that */
3194 if (!IS_IFX (tree->left))
3195 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3197 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3198 /* right is a IFX then just join */
3199 if (IS_IFX (tree->right))
3200 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3202 tree->right = createLabel (localLabel, tree->right);
3203 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3205 return newNode (NULLOP, tree->left, tree->right);
3211 int wasnot = IS_NOT (tree->left);
3212 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3214 /* if the left is already a IFX */
3215 if (!IS_IFX (tree->left))
3216 tree->left = newNode (IFX, tree->left, NULL);
3220 tree->left->trueLabel = trueLabel;
3221 tree->left->falseLabel = falseLabel;
3225 tree->left->trueLabel = falseLabel;
3226 tree->left->falseLabel = trueLabel;
3233 tree->trueLabel = trueLabel;
3234 tree->falseLabel = falseLabel;
3241 /*-----------------------------------------------------------------*/
3242 /* createBlock - create expression tree for block */
3243 /*-----------------------------------------------------------------*/
3245 createBlock (symbol * decl, ast * body)
3249 /* if the block has nothing */
3253 ex = newNode (BLOCK, NULL, body);
3254 ex->values.sym = decl;
3256 ex->right = ex->right;
3262 /*-----------------------------------------------------------------*/
3263 /* createLabel - creates the expression tree for labels */
3264 /*-----------------------------------------------------------------*/
3266 createLabel (symbol * label, ast * stmnt)
3269 char name[SDCC_NAME_MAX + 1];
3272 /* must create fresh symbol if the symbol name */
3273 /* exists in the symbol table, since there can */
3274 /* be a variable with the same name as the labl */
3275 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3276 (csym->level == label->level))
3277 label = newSymbol (label->name, label->level);
3279 /* change the name before putting it in add _ */
3280 sprintf (name, "%s", label->name);
3282 /* put the label in the LabelSymbol table */
3283 /* but first check if a label of the same */
3285 if ((csym = findSym (LabelTab, NULL, name)))
3286 werror (E_DUPLICATE_LABEL, label->name);
3288 addSym (LabelTab, label, name, label->level, 0);
3291 label->key = labelKey++;
3292 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3298 /*-----------------------------------------------------------------*/
3299 /* createCase - generates the parsetree for a case statement */
3300 /*-----------------------------------------------------------------*/
3302 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3304 char caseLbl[SDCC_NAME_MAX + 1];
3308 /* if the switch statement does not exist */
3309 /* then case is out of context */
3312 werror (E_CASE_CONTEXT);
3316 caseVal = decorateType (resolveSymbols (caseVal));
3317 /* if not a constant then error */
3318 if (!IS_LITERAL (caseVal->ftype))
3320 werror (E_CASE_CONSTANT);
3324 /* if not a integer than error */
3325 if (!IS_INTEGRAL (caseVal->ftype))
3327 werror (E_CASE_NON_INTEGER);
3331 /* find the end of the switch values chain */
3332 if (!(val = swStat->values.switchVals.swVals))
3333 swStat->values.switchVals.swVals = caseVal->opval.val;
3336 /* also order the cases according to value */
3338 int cVal = (int) floatFromVal (caseVal->opval.val);
3339 while (val && (int) floatFromVal (val) < cVal)
3345 /* if we reached the end then */
3348 pval->next = caseVal->opval.val;
3352 /* we found a value greater than */
3353 /* the current value we must add this */
3354 /* before the value */
3355 caseVal->opval.val->next = val;
3357 /* if this was the first in chain */
3358 if (swStat->values.switchVals.swVals == val)
3359 swStat->values.switchVals.swVals =
3362 pval->next = caseVal->opval.val;
3367 /* create the case label */
3368 sprintf (caseLbl, "_case_%d_%d",
3369 swStat->values.switchVals.swNum,
3370 (int) floatFromVal (caseVal->opval.val));
3372 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3377 /*-----------------------------------------------------------------*/
3378 /* createDefault - creates the parse tree for the default statement */
3379 /*-----------------------------------------------------------------*/
3381 createDefault (ast * swStat, ast * stmnt)
3383 char defLbl[SDCC_NAME_MAX + 1];
3385 /* if the switch statement does not exist */
3386 /* then case is out of context */
3389 werror (E_CASE_CONTEXT);
3393 /* turn on the default flag */
3394 swStat->values.switchVals.swDefault = 1;
3396 /* create the label */
3397 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3398 return createLabel (newSymbol (defLbl, 0), stmnt);
3401 /*-----------------------------------------------------------------*/
3402 /* createIf - creates the parsetree for the if statement */
3403 /*-----------------------------------------------------------------*/
3405 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3407 static int Lblnum = 0;
3409 symbol *ifTrue, *ifFalse, *ifEnd;
3411 /* if neither exists */
3412 if (!elseBody && !ifBody)
3415 /* create the labels */
3416 sprintf (buffer, "_iffalse_%d", Lblnum);
3417 ifFalse = newSymbol (buffer, NestLevel);
3418 /* if no else body then end == false */
3423 sprintf (buffer, "_ifend_%d", Lblnum);
3424 ifEnd = newSymbol (buffer, NestLevel);
3427 sprintf (buffer, "_iftrue_%d", Lblnum);
3428 ifTrue = newSymbol (buffer, NestLevel);
3432 /* attach the ifTrue label to the top of it body */
3433 ifBody = createLabel (ifTrue, ifBody);
3434 /* attach a goto end to the ifBody if else is present */
3437 ifBody = newNode (NULLOP, ifBody,
3439 newAst_VALUE (symbolVal (ifEnd)),
3441 /* put the elseLabel on the else body */
3442 elseBody = createLabel (ifFalse, elseBody);
3443 /* out the end at the end of the body */
3444 elseBody = newNode (NULLOP,
3446 createLabel (ifEnd, NULL));
3450 ifBody = newNode (NULLOP, ifBody,
3451 createLabel (ifFalse, NULL));
3453 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3454 if (IS_IFX (condAst))
3457 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3459 return newNode (NULLOP, ifTree,
3460 newNode (NULLOP, ifBody, elseBody));
3464 /*-----------------------------------------------------------------*/
3465 /* createDo - creates parse tree for do */
3468 /* _docontinue_n: */
3469 /* condition_expression +-> trueLabel -> _dobody_n */
3471 /* +-> falseLabel-> _dobreak_n */
3473 /*-----------------------------------------------------------------*/
3475 createDo (symbol * trueLabel, symbol * continueLabel,
3476 symbol * falseLabel, ast * condAst, ast * doBody)
3481 /* if the body does not exist then it is simple */
3484 condAst = backPatchLabels (condAst, continueLabel, NULL);
3485 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3486 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3487 doTree->trueLabel = continueLabel;
3488 doTree->falseLabel = NULL;
3492 /* otherwise we have a body */
3493 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3495 /* attach the body label to the top */
3496 doBody = createLabel (trueLabel, doBody);
3497 /* attach the continue label to end of body */
3498 doBody = newNode (NULLOP, doBody,
3499 createLabel (continueLabel, NULL));
3501 /* now put the break label at the end */
3502 if (IS_IFX (condAst))
3505 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3507 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3509 /* putting it together */
3510 return newNode (NULLOP, doBody, doTree);
3513 /*-----------------------------------------------------------------*/
3514 /* createFor - creates parse tree for 'for' statement */
3517 /* condExpr +-> trueLabel -> _forbody_n */
3519 /* +-> falseLabel-> _forbreak_n */
3522 /* _forcontinue_n: */
3524 /* goto _forcond_n ; */
3526 /*-----------------------------------------------------------------*/
3528 createFor (symbol * trueLabel, symbol * continueLabel,
3529 symbol * falseLabel, symbol * condLabel,
3530 ast * initExpr, ast * condExpr, ast * loopExpr,
3535 /* if loopexpression not present then we can generate it */
3536 /* the same way as a while */
3538 return newNode (NULLOP, initExpr,
3539 createWhile (trueLabel, continueLabel,
3540 falseLabel, condExpr, forBody));
3541 /* vanilla for statement */
3542 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3544 if (condExpr && !IS_IFX (condExpr))
3545 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3548 /* attach condition label to condition */
3549 condExpr = createLabel (condLabel, condExpr);
3551 /* attach body label to body */
3552 forBody = createLabel (trueLabel, forBody);
3554 /* attach continue to forLoop expression & attach */
3555 /* goto the forcond @ and of loopExpression */
3556 loopExpr = createLabel (continueLabel,
3560 newAst_VALUE (symbolVal (condLabel)),
3562 /* now start putting them together */
3563 forTree = newNode (NULLOP, initExpr, condExpr);
3564 forTree = newNode (NULLOP, forTree, forBody);
3565 forTree = newNode (NULLOP, forTree, loopExpr);
3566 /* finally add the break label */
3567 forTree = newNode (NULLOP, forTree,
3568 createLabel (falseLabel, NULL));
3572 /*-----------------------------------------------------------------*/
3573 /* createWhile - creates parse tree for while statement */
3574 /* the while statement will be created as follows */
3576 /* _while_continue_n: */
3577 /* condition_expression +-> trueLabel -> _while_boby_n */
3579 /* +-> falseLabel -> _while_break_n */
3580 /* _while_body_n: */
3582 /* goto _while_continue_n */
3583 /* _while_break_n: */
3584 /*-----------------------------------------------------------------*/
3586 createWhile (symbol * trueLabel, symbol * continueLabel,
3587 symbol * falseLabel, ast * condExpr, ast * whileBody)
3591 /* put the continue label */
3592 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3593 condExpr = createLabel (continueLabel, condExpr);
3594 condExpr->lineno = 0;
3596 /* put the body label in front of the body */
3597 whileBody = createLabel (trueLabel, whileBody);
3598 whileBody->lineno = 0;
3599 /* put a jump to continue at the end of the body */
3600 /* and put break label at the end of the body */
3601 whileBody = newNode (NULLOP,
3604 newAst_VALUE (symbolVal (continueLabel)),
3605 createLabel (falseLabel, NULL)));
3607 /* put it all together */
3608 if (IS_IFX (condExpr))
3609 whileTree = condExpr;
3612 whileTree = newNode (IFX, condExpr, NULL);
3613 /* put the true & false labels in place */
3614 whileTree->trueLabel = trueLabel;
3615 whileTree->falseLabel = falseLabel;
3618 return newNode (NULLOP, whileTree, whileBody);
3621 /*-----------------------------------------------------------------*/
3622 /* optimizeGetHbit - get highest order bit of the expression */
3623 /*-----------------------------------------------------------------*/
3625 optimizeGetHbit (ast * tree)
3628 /* if this is not a bit and */
3629 if (!IS_BITAND (tree))
3632 /* will look for tree of the form
3633 ( expr >> ((sizeof expr) -1) ) & 1 */
3634 if (!IS_AST_LIT_VALUE (tree->right))
3637 if (AST_LIT_VALUE (tree->right) != 1)
3640 if (!IS_RIGHT_OP (tree->left))
3643 if (!IS_AST_LIT_VALUE (tree->left->right))
3646 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3647 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3650 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3654 /*-----------------------------------------------------------------*/
3655 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3656 /*-----------------------------------------------------------------*/
3658 optimizeRRCRLC (ast * root)
3660 /* will look for trees of the form
3661 (?expr << 1) | (?expr >> 7) or
3662 (?expr >> 7) | (?expr << 1) will make that
3663 into a RLC : operation ..
3665 (?expr >> 1) | (?expr << 7) or
3666 (?expr << 7) | (?expr >> 1) will make that
3667 into a RRC operation
3668 note : by 7 I mean (number of bits required to hold the
3670 /* if the root operations is not a | operation the not */
3671 if (!IS_BITOR (root))
3674 /* I have to think of a better way to match patterns this sucks */
3675 /* that aside let start looking for the first case : I use a the
3676 negative check a lot to improve the efficiency */
3677 /* (?expr << 1) | (?expr >> 7) */
3678 if (IS_LEFT_OP (root->left) &&
3679 IS_RIGHT_OP (root->right))
3682 if (!SPEC_USIGN (TETYPE (root->left->left)))
3685 if (!IS_AST_LIT_VALUE (root->left->right) ||
3686 !IS_AST_LIT_VALUE (root->right->right))
3689 /* make sure it is the same expression */
3690 if (!isAstEqual (root->left->left,
3694 if (AST_LIT_VALUE (root->left->right) != 1)
3697 if (AST_LIT_VALUE (root->right->right) !=
3698 (getSize (TTYPE (root->left->left)) * 8 - 1))
3701 /* whew got the first case : create the AST */
3702 return newNode (RLC, root->left->left, NULL);
3706 /* check for second case */
3707 /* (?expr >> 7) | (?expr << 1) */
3708 if (IS_LEFT_OP (root->right) &&
3709 IS_RIGHT_OP (root->left))
3712 if (!SPEC_USIGN (TETYPE (root->left->left)))
3715 if (!IS_AST_LIT_VALUE (root->left->right) ||
3716 !IS_AST_LIT_VALUE (root->right->right))
3719 /* make sure it is the same symbol */
3720 if (!isAstEqual (root->left->left,
3724 if (AST_LIT_VALUE (root->right->right) != 1)
3727 if (AST_LIT_VALUE (root->left->right) !=
3728 (getSize (TTYPE (root->left->left)) * 8 - 1))
3731 /* whew got the first case : create the AST */
3732 return newNode (RLC, root->left->left, NULL);
3737 /* third case for RRC */
3738 /* (?symbol >> 1) | (?symbol << 7) */
3739 if (IS_LEFT_OP (root->right) &&
3740 IS_RIGHT_OP (root->left))
3743 if (!SPEC_USIGN (TETYPE (root->left->left)))
3746 if (!IS_AST_LIT_VALUE (root->left->right) ||
3747 !IS_AST_LIT_VALUE (root->right->right))
3750 /* make sure it is the same symbol */
3751 if (!isAstEqual (root->left->left,
3755 if (AST_LIT_VALUE (root->left->right) != 1)
3758 if (AST_LIT_VALUE (root->right->right) !=
3759 (getSize (TTYPE (root->left->left)) * 8 - 1))
3762 /* whew got the first case : create the AST */
3763 return newNode (RRC, root->left->left, NULL);
3767 /* fourth and last case for now */
3768 /* (?symbol << 7) | (?symbol >> 1) */
3769 if (IS_RIGHT_OP (root->right) &&
3770 IS_LEFT_OP (root->left))
3773 if (!SPEC_USIGN (TETYPE (root->left->left)))
3776 if (!IS_AST_LIT_VALUE (root->left->right) ||
3777 !IS_AST_LIT_VALUE (root->right->right))
3780 /* make sure it is the same symbol */
3781 if (!isAstEqual (root->left->left,
3785 if (AST_LIT_VALUE (root->right->right) != 1)
3788 if (AST_LIT_VALUE (root->left->right) !=
3789 (getSize (TTYPE (root->left->left)) * 8 - 1))
3792 /* whew got the first case : create the AST */
3793 return newNode (RRC, root->left->left, NULL);
3797 /* not found return root */
3801 /*-----------------------------------------------------------------*/
3802 /* optimizeCompare - otimizes compares for bit variables */
3803 /*-----------------------------------------------------------------*/
3805 optimizeCompare (ast * root)
3807 ast *optExpr = NULL;
3810 unsigned int litValue;
3812 /* if nothing then return nothing */
3816 /* if not a compare op then do leaves */
3817 if (!IS_COMPARE_OP (root))
3819 root->left = optimizeCompare (root->left);
3820 root->right = optimizeCompare (root->right);
3824 /* if left & right are the same then depending
3825 of the operation do */
3826 if (isAstEqual (root->left, root->right))
3828 switch (root->opval.op)
3833 optExpr = newAst_VALUE (constVal ("0"));
3838 optExpr = newAst_VALUE (constVal ("1"));
3842 return decorateType (optExpr);
3845 vleft = (root->left->type == EX_VALUE ?
3846 root->left->opval.val : NULL);
3848 vright = (root->right->type == EX_VALUE ?
3849 root->right->opval.val : NULL);
3851 /* if left is a BITVAR in BITSPACE */
3852 /* and right is a LITERAL then opt- */
3853 /* imize else do nothing */
3854 if (vleft && vright &&
3855 IS_BITVAR (vleft->etype) &&
3856 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3857 IS_LITERAL (vright->etype))
3860 /* if right side > 1 then comparison may never succeed */
3861 if ((litValue = (int) floatFromVal (vright)) > 1)
3863 werror (W_BAD_COMPARE);
3869 switch (root->opval.op)
3871 case '>': /* bit value greater than 1 cannot be */
3872 werror (W_BAD_COMPARE);
3876 case '<': /* bit value < 1 means 0 */
3878 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3881 case LE_OP: /* bit value <= 1 means no check */
3882 optExpr = newAst_VALUE (vright);
3885 case GE_OP: /* bit value >= 1 means only check for = */
3887 optExpr = newAst_VALUE (vleft);
3892 { /* literal is zero */
3893 switch (root->opval.op)
3895 case '<': /* bit value < 0 cannot be */
3896 werror (W_BAD_COMPARE);
3900 case '>': /* bit value > 0 means 1 */
3902 optExpr = newAst_VALUE (vleft);
3905 case LE_OP: /* bit value <= 0 means no check */
3906 case GE_OP: /* bit value >= 0 means no check */
3907 werror (W_BAD_COMPARE);
3911 case EQ_OP: /* bit == 0 means ! of bit */
3912 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3916 return decorateType (resolveSymbols (optExpr));
3917 } /* end-of-if of BITVAR */
3922 /*-----------------------------------------------------------------*/
3923 /* addSymToBlock : adds the symbol to the first block we find */
3924 /*-----------------------------------------------------------------*/
3926 addSymToBlock (symbol * sym, ast * tree)
3928 /* reached end of tree or a leaf */
3929 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3933 if (IS_AST_OP (tree) &&
3934 tree->opval.op == BLOCK)
3937 symbol *lsym = copySymbol (sym);
3939 lsym->next = AST_VALUES (tree, sym);
3940 AST_VALUES (tree, sym) = lsym;
3944 addSymToBlock (sym, tree->left);
3945 addSymToBlock (sym, tree->right);
3948 /*-----------------------------------------------------------------*/
3949 /* processRegParms - do processing for register parameters */
3950 /*-----------------------------------------------------------------*/
3952 processRegParms (value * args, ast * body)
3956 if (IS_REGPARM (args->etype))
3957 addSymToBlock (args->sym, body);
3962 /*-----------------------------------------------------------------*/
3963 /* resetParmKey - resets the operandkeys for the symbols */
3964 /*-----------------------------------------------------------------*/
3965 DEFSETFUNC (resetParmKey)
3976 /*-----------------------------------------------------------------*/
3977 /* createFunction - This is the key node that calls the iCode for */
3978 /* generating the code for a function. Note code */
3979 /* is generated function by function, later when */
3980 /* add inter-procedural analysis this will change */
3981 /*-----------------------------------------------------------------*/
3983 createFunction (symbol * name, ast * body)
3989 iCode *piCode = NULL;
3991 /* if check function return 0 then some problem */
3992 if (checkFunction (name) == 0)
3995 /* create a dummy block if none exists */
3997 body = newNode (BLOCK, NULL, NULL);
4001 /* check if the function name already in the symbol table */
4002 if ((csym = findSym (SymbolTab, NULL, name->name)))
4005 /* special case for compiler defined functions
4006 we need to add the name to the publics list : this
4007 actually means we are now compiling the compiler
4011 addSet (&publics, name);
4017 allocVariables (name);
4019 name->lastLine = yylineno;
4021 processFuncArgs (currFunc, 0);
4023 /* set the stack pointer */
4024 /* PENDING: check this for the mcs51 */
4025 stackPtr = -port->stack.direction * port->stack.call_overhead;
4026 if (IS_ISR (name->etype))
4027 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4028 if (IS_RENT (name->etype) || options.stackAuto)
4029 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4031 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4033 fetype = getSpec (name->type); /* get the specifier for the function */
4034 /* if this is a reentrant function then */
4035 if (IS_RENT (fetype))
4038 allocParms (name->args); /* allocate the parameters */
4040 /* do processing for parameters that are passed in registers */
4041 processRegParms (name->args, body);
4043 /* set the stack pointer */
4047 /* allocate & autoinit the block variables */
4048 processBlockVars (body, &stack, ALLOCATE);
4050 /* save the stack information */
4051 if (options.useXstack)
4052 name->xstack = SPEC_STAK (fetype) = stack;
4054 name->stack = SPEC_STAK (fetype) = stack;
4056 /* name needs to be mangled */
4057 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4059 body = resolveSymbols (body); /* resolve the symbols */
4060 body = decorateType (body); /* propagateType & do semantic checks */
4062 ex = newAst_VALUE (symbolVal (name)); /* create name */
4063 ex = newNode (FUNCTION, ex, body);
4064 ex->values.args = name->args;
4068 werror (E_FUNC_NO_CODE, name->name);
4072 /* create the node & generate intermediate code */
4073 codeOutFile = code->oFile;
4074 piCode = iCodeFromAst (ex);
4078 werror (E_FUNC_NO_CODE, name->name);
4082 eBBlockFromiCode (piCode);
4084 /* if there are any statics then do them */
4087 codeOutFile = statsg->oFile;
4088 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4094 /* dealloc the block variables */
4095 processBlockVars (body, &stack, DEALLOCATE);
4096 /* deallocate paramaters */
4097 deallocParms (name->args);
4099 if (IS_RENT (fetype))
4102 /* we are done freeup memory & cleanup */
4107 addSet (&operKeyReset, name);
4108 applyToSet (operKeyReset, resetParmKey);
4110 if (options.debug && !options.nodebug)
4111 cdbStructBlock (1, cdbFile);
4113 cleanUpLevel (LabelTab, 0);
4114 cleanUpBlock (StructTab, 1);
4115 cleanUpBlock (TypedefTab, 1);
4117 xstack->syms = NULL;
4118 istack->syms = NULL;