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 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *, RESULT_TYPE);
59 ast *optimizeGetAbit (ast *, RESULT_TYPE);
60 ast *optimizeGetByte (ast *, RESULT_TYPE);
61 ast *optimizeGetWord (ast *, RESULT_TYPE);
62 static ast *backPatchLabels (ast *, symbol *, symbol *);
65 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
70 printTypeChain (tree->ftype, stdout);
75 /*-----------------------------------------------------------------*/
76 /* newAst - creates a fresh node for an expression tree */
77 /*-----------------------------------------------------------------*/
79 newAst_ (unsigned type)
82 static int oldLineno = 0;
84 ex = Safe_alloc ( sizeof (ast));
87 ex->lineno = (noLineno ? oldLineno : mylineno);
88 ex->filename = currFname;
89 ex->level = NestLevel;
90 ex->block = currBlockno;
91 ex->initMode = inInitMode;
92 ex->seqPoint = seqPointNo;
97 newAst_VALUE (value * val)
99 ast *ex = newAst_ (EX_VALUE);
105 newAst_OP (unsigned op)
107 ast *ex = newAst_ (EX_OP);
113 newAst_LINK (sym_link * val)
115 ast *ex = newAst_ (EX_LINK);
120 /*-----------------------------------------------------------------*/
121 /* newNode - creates a new node */
122 /*-----------------------------------------------------------------*/
124 newNode (long op, ast * left, ast * right)
135 /*-----------------------------------------------------------------*/
136 /* newIfxNode - creates a new Ifx Node */
137 /*-----------------------------------------------------------------*/
139 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
143 /* if this is a literal then we already know the result */
144 if (condAst->etype && IS_LITERAL (condAst->etype))
146 /* then depending on the expression value */
147 if (floatFromVal (condAst->opval.val))
148 ifxNode = newNode (GOTO,
149 newAst_VALUE (symbolVal (trueLabel)),
152 ifxNode = newNode (GOTO,
153 newAst_VALUE (symbolVal (falseLabel)),
158 ifxNode = newNode (IFX, condAst, NULL);
159 ifxNode->trueLabel = trueLabel;
160 ifxNode->falseLabel = falseLabel;
166 /*-----------------------------------------------------------------*/
167 /* copyAstValues - copies value portion of ast if needed */
168 /*-----------------------------------------------------------------*/
170 copyAstValues (ast * dest, ast * src)
172 switch (src->opval.op)
175 dest->values.sym = copySymbolChain (src->values.sym);
179 dest->values.switchVals.swVals =
180 copyValue (src->values.switchVals.swVals);
181 dest->values.switchVals.swDefault =
182 src->values.switchVals.swDefault;
183 dest->values.switchVals.swNum =
184 src->values.switchVals.swNum;
188 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
192 dest->values.constlist = copyLiteralList(src->values.constlist);
196 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
197 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
198 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
199 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
200 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
201 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
202 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
207 /*-----------------------------------------------------------------*/
208 /* copyAst - makes a copy of a given astession */
209 /*-----------------------------------------------------------------*/
218 dest = Safe_alloc ( sizeof (ast));
220 dest->type = src->type;
221 dest->lineno = src->lineno;
222 dest->level = src->level;
223 dest->funcName = src->funcName;
224 dest->reversed = src->reversed;
227 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
229 /* if this is a leaf */
231 if (src->type == EX_VALUE)
233 dest->opval.val = copyValue (src->opval.val);
238 if (src->type == EX_LINK)
240 dest->opval.lnk = copyLinkChain (src->opval.lnk);
244 dest->opval.op = src->opval.op;
246 /* if this is a node that has special values */
247 copyAstValues (dest, src);
249 dest->trueLabel = copySymbol (src->trueLabel);
250 dest->falseLabel = copySymbol (src->falseLabel);
251 dest->left = copyAst (src->left);
252 dest->right = copyAst (src->right);
258 /*-----------------------------------------------------------------*/
259 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
260 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
261 /*-----------------------------------------------------------------*/
262 ast *removeIncDecOps (ast * tree) {
264 // traverse the tree and remove inc/dec ops
269 if (tree->type == EX_OP &&
270 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
277 tree->left=removeIncDecOps(tree->left);
278 tree->right=removeIncDecOps(tree->right);
283 /*-----------------------------------------------------------------*/
284 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
285 /* "*++s += 3" -> "*++s = *++s + 3" */
286 /*-----------------------------------------------------------------*/
287 ast *removePreIncDecOps (ast * tree) {
289 // traverse the tree and remove pre-inc/dec ops
294 if (tree->type == EX_OP &&
295 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
300 tree->left=removePreIncDecOps(tree->left);
301 tree->right=removePreIncDecOps(tree->right);
306 /*-----------------------------------------------------------------*/
307 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
308 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
309 /*-----------------------------------------------------------------*/
310 ast *removePostIncDecOps (ast * tree) {
312 // traverse the tree and remove pre-inc/dec ops
317 if (tree->type == EX_OP &&
318 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
323 tree->left=removePostIncDecOps(tree->left);
324 tree->right=removePostIncDecOps(tree->right);
329 /*-----------------------------------------------------------------*/
330 /* hasSEFcalls - returns TRUE if tree has a function call */
331 /*-----------------------------------------------------------------*/
333 hasSEFcalls (ast * tree)
338 if (tree->type == EX_OP &&
339 (tree->opval.op == CALL ||
340 tree->opval.op == PCALL ||
341 tree->opval.op == '=' ||
342 tree->opval.op == INC_OP ||
343 tree->opval.op == DEC_OP))
346 return (hasSEFcalls (tree->left) |
347 hasSEFcalls (tree->right));
350 /*-----------------------------------------------------------------*/
351 /* isAstEqual - compares two asts & returns 1 if they are equal */
352 /*-----------------------------------------------------------------*/
354 isAstEqual (ast * t1, ast * t2)
363 if (t1->type != t2->type)
369 if (t1->opval.op != t2->opval.op)
371 return (isAstEqual (t1->left, t2->left) &&
372 isAstEqual (t1->right, t2->right));
376 if (t1->opval.val->sym)
378 if (!t2->opval.val->sym)
381 return isSymbolEqual (t1->opval.val->sym,
386 if (t2->opval.val->sym)
389 return (floatFromVal (t1->opval.val) ==
390 floatFromVal (t2->opval.val));
394 /* only compare these two types */
402 /*-----------------------------------------------------------------*/
403 /* resolveSymbols - resolve symbols from the symbol table */
404 /*-----------------------------------------------------------------*/
406 resolveSymbols (ast * tree)
408 /* walk the entire tree and check for values */
409 /* with symbols if we find one then replace */
410 /* symbol with that from the symbol table */
417 /* if not block & function */
418 if (tree->type == EX_OP &&
419 (tree->opval.op != FUNCTION &&
420 tree->opval.op != BLOCK &&
421 tree->opval.op != NULLOP))
423 filename = tree->filename;
424 lineno = tree->lineno;
428 /* make sure we resolve the true & false labels for ifx */
429 if (tree->type == EX_OP && tree->opval.op == IFX)
435 if ((csym = findSym (LabelTab, tree->trueLabel,
436 tree->trueLabel->name)))
437 tree->trueLabel = csym;
439 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
440 tree->trueLabel->name);
443 if (tree->falseLabel)
445 if ((csym = findSym (LabelTab,
447 tree->falseLabel->name)))
448 tree->falseLabel = csym;
450 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
451 tree->falseLabel->name);
456 /* if this is a label resolve it from the labelTab */
457 if (IS_AST_VALUE (tree) &&
458 tree->opval.val->sym &&
459 tree->opval.val->sym->islbl)
462 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
463 tree->opval.val->sym->name);
466 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
467 tree->opval.val->sym->name);
469 tree->opval.val->sym = csym;
471 goto resolveChildren;
474 /* do only for leafs */
475 if (IS_AST_VALUE (tree) &&
476 tree->opval.val->sym &&
477 !tree->opval.val->sym->implicit)
480 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
482 /* if found in the symbol table & they r not the same */
483 if (csym && tree->opval.val->sym != csym)
485 tree->opval.val->sym = csym;
486 tree->opval.val->type = csym->type;
487 tree->opval.val->etype = csym->etype;
490 /* if not found in the symbol table */
491 /* mark it as undefined assume it is */
492 /* an integer in data space */
493 if (!csym && !tree->opval.val->sym->implicit)
496 /* if this is a function name then */
497 /* mark it as returning an int */
500 tree->opval.val->sym->type = newLink (DECLARATOR);
501 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
502 tree->opval.val->sym->type->next =
503 tree->opval.val->sym->etype = newIntLink ();
504 tree->opval.val->etype = tree->opval.val->etype;
505 tree->opval.val->type = tree->opval.val->sym->type;
506 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
507 tree->opval.val->sym->name);
508 //tree->opval.val->sym->undefined = 1;
509 allocVariables (tree->opval.val->sym);
513 tree->opval.val->sym->undefined = 1;
514 tree->opval.val->type =
515 tree->opval.val->etype = newIntLink ();
516 tree->opval.val->sym->type =
517 tree->opval.val->sym->etype = newIntLink ();
523 resolveSymbols (tree->left);
524 resolveSymbols (tree->right);
529 /*-----------------------------------------------------------------*/
530 /* setAstLineno - walks a ast tree & sets the line number */
531 /*-----------------------------------------------------------------*/
532 int setAstLineno (ast * tree, int lineno)
537 tree->lineno = lineno;
538 setAstLineno (tree->left, lineno);
539 setAstLineno (tree->right, lineno);
543 /*-----------------------------------------------------------------*/
544 /* funcOfType :- function of type with name */
545 /*-----------------------------------------------------------------*/
547 funcOfType (char *name, sym_link * type, sym_link * argType,
551 /* create the symbol */
552 sym = newSymbol (name, 0);
554 /* setup return value */
555 sym->type = newLink (DECLARATOR);
556 DCL_TYPE (sym->type) = FUNCTION;
557 sym->type->next = copyLinkChain (type);
558 sym->etype = getSpec (sym->type);
559 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
561 /* if arguments required */
565 args = FUNC_ARGS(sym->type) = newValue ();
569 args->type = copyLinkChain (argType);
570 args->etype = getSpec (args->type);
571 SPEC_EXTR(args->etype)=1;
574 args = args->next = newValue ();
581 allocVariables (sym);
586 /*-----------------------------------------------------------------*/
587 /* funcOfTypeVarg :- function of type with name and argtype */
588 /*-----------------------------------------------------------------*/
590 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
595 /* create the symbol */
596 sym = newSymbol (name, 0);
598 /* setup return value */
599 sym->type = newLink (DECLARATOR);
600 DCL_TYPE (sym->type) = FUNCTION;
601 sym->type->next = typeFromStr(rtype);
602 sym->etype = getSpec (sym->type);
604 /* if arguments required */
607 args = FUNC_ARGS(sym->type) = newValue ();
609 for ( i = 0 ; i < nArgs ; i++ ) {
610 args->type = typeFromStr(atypes[i]);
611 args->etype = getSpec (args->type);
612 SPEC_EXTR(args->etype)=1;
613 if ((i + 1) == nArgs) break;
614 args = args->next = newValue ();
621 allocVariables (sym);
626 /*-----------------------------------------------------------------*/
627 /* reverseParms - will reverse a parameter tree */
628 /*-----------------------------------------------------------------*/
630 reverseParms (ast * ptree)
636 /* top down if we find a nonParm tree then quit */
637 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
639 /* The various functions expect the parameter tree to be right heavy. */
640 /* Rotate the tree to be left heavy so that after reversal it is */
641 /* right heavy again. */
642 while ((ttree = ptree->right) && ttree->type == EX_OP &&
643 ttree->opval.op == PARAM)
645 ptree->right = ttree->right;
646 ttree->right = ttree->left;
647 ttree->left = ptree->left;
653 ptree->left = ptree->right;
654 ptree->right = ttree;
656 reverseParms (ptree->left);
657 reverseParms (ptree->right);
663 /*-----------------------------------------------------------------*/
664 /* processParms - makes sure the parameters are okay and do some */
665 /* processing with them */
666 /*-----------------------------------------------------------------*/
668 processParms (ast *func,
671 int *parmNumber, /* unused, although updated */
674 RESULT_TYPE resultType;
677 /* if none of them exist */
678 if (!defParm && !*actParm)
683 if (getenv("DEBUG_SANITY"))
685 fprintf (stderr, "processParms: %s ", defParm->name);
687 /* make sure the type is complete and sane */
688 checkTypeSanity(defParm->etype, defParm->name);
691 if (IS_CODEPTR (func->ftype))
692 functype = func->ftype->next;
694 functype = func->ftype;
696 /* if the function is being called via a pointer & */
697 /* it has not been defined a reentrant then we cannot */
698 /* have parameters */
699 /* PIC16 port can... */
700 if (!TARGET_IS_PIC16)
702 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
704 werror (W_NONRENT_ARGS);
710 /* if defined parameters ended but actual parameters */
711 /* exist and this is not defined as a variable arg */
712 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
714 werror (E_TOO_MANY_PARMS);
718 /* if defined parameters present but no actual parameters */
719 if (defParm && !*actParm)
721 werror (E_TOO_FEW_PARMS);
725 /* if this is a PARAM node then match left & right */
726 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
728 (*actParm)->decorated = 1;
729 return (processParms (func, defParm,
730 &(*actParm)->left, parmNumber, FALSE) ||
731 processParms (func, defParm ? defParm->next : NULL,
732 &(*actParm)->right, parmNumber, rightmost));
734 else if (defParm) /* not vararg */
736 /* If we have found a value node by following only right-hand links,
737 * then we know that there are no more values after us.
739 * Therefore, if there are more defined parameters, the caller didn't
742 if (rightmost && defParm->next)
744 werror (E_TOO_FEW_PARMS);
749 /* decorate parameter */
750 resultType = defParm ? getResultTypeFromType (defParm->type) :
752 *actParm = decorateType (*actParm, resultType);
754 if (IS_VOID((*actParm)->ftype))
756 werror (E_VOID_VALUE_USED);
760 /* If this is a varargs function... */
761 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
766 if (IS_CAST_OP (*actParm)
767 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
769 /* Parameter was explicitly typecast; don't touch it. */
773 ftype = (*actParm)->ftype;
775 /* If it's a char, upcast to int. */
776 if (IS_INTEGRAL (ftype)
777 && (getSize (ftype) < (unsigned) INTSIZE))
779 newType = newAst_LINK(INTTYPE);
782 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
784 newType = newAst_LINK (copyLinkChain(ftype));
785 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
788 if (IS_AGGREGATE (ftype))
790 newType = newAst_LINK (copyLinkChain (ftype));
791 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
796 /* cast required; change this op to a cast. */
797 (*actParm)->decorated = 0;
798 *actParm = newNode (CAST, newType, *actParm);
799 (*actParm)->lineno = (*actParm)->right->lineno;
801 decorateType (*actParm, RESULT_TYPE_NONE);
806 /* if defined parameters ended but actual has not & */
808 if (!defParm && *actParm &&
809 (options.stackAuto || IFFUNC_ISREENT (functype)))
812 resolveSymbols (*actParm);
814 /* the parameter type must be at least castable */
815 if (compareType (defParm->type, (*actParm)->ftype) == 0)
817 werror (E_INCOMPAT_TYPES);
818 printFromToType ((*actParm)->ftype, defParm->type);
822 /* if the parameter is castable then add the cast */
823 if (compareType (defParm->type, (*actParm)->ftype) < 0)
827 resultType = getResultTypeFromType (defParm->etype);
828 pTree = resolveSymbols (copyAst (*actParm));
830 /* now change the current one to a cast */
831 (*actParm)->type = EX_OP;
832 (*actParm)->opval.op = CAST;
833 (*actParm)->left = newAst_LINK (defParm->type);
834 (*actParm)->right = pTree;
835 (*actParm)->decorated = 0; /* force typechecking */
836 decorateType (*actParm, resultType);
839 /* make a copy and change the regparm type to the defined parm */
840 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
841 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
842 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
847 /*-----------------------------------------------------------------*/
848 /* createIvalType - generates ival for basic types */
849 /*-----------------------------------------------------------------*/
851 createIvalType (ast * sym, sym_link * type, initList * ilist)
855 /* if initList is deep */
856 if (ilist->type == INIT_DEEP)
857 ilist = ilist->init.deep;
859 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
860 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
863 /*-----------------------------------------------------------------*/
864 /* createIvalStruct - generates initial value for structures */
865 /*-----------------------------------------------------------------*/
867 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
874 sflds = SPEC_STRUCT (type)->fields;
875 if (ilist->type != INIT_DEEP)
877 werror (E_INIT_STRUCT, "");
881 iloop = ilist->init.deep;
883 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
885 /* if we have come to end */
889 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
890 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
891 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
892 iloop, rast, rootValue)),
898 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
899 W_EXCESS_INITIALIZERS, "struct",
900 sym->opval.val->sym->name);
907 /*-----------------------------------------------------------------*/
908 /* createIvalArray - generates code for array initialization */
909 /*-----------------------------------------------------------------*/
911 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
915 int lcnt = 0, size = 0;
916 literalList *literalL;
918 /* take care of the special case */
919 /* array of characters can be init */
921 if (IS_CHAR (type->next))
922 if ((rast = createIvalCharPtr (sym,
924 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
927 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
929 /* not the special case */
930 if (ilist->type != INIT_DEEP)
932 werror (E_INIT_STRUCT, "");
936 iloop = ilist->init.deep;
937 lcnt = DCL_ELEM (type);
939 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
943 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
945 rast = newNode(ARRAYINIT, aSym, NULL);
946 rast->values.constlist = literalL;
948 // Make sure size is set to length of initializer list.
955 if (lcnt && size > lcnt)
957 // Array size was specified, and we have more initializers than needed.
958 char *name=sym->opval.val->sym->name;
959 int lineno=sym->opval.val->sym->lineDef;
960 char *filename=sym->opval.val->sym->fileDef;
962 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
971 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
972 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
973 rast = createIval (aSym, type->next, iloop, rast, rootValue);
974 iloop = (iloop ? iloop->next : NULL);
980 /* no of elements given and we */
981 /* have generated for all of them */
984 // is this a better way? at least it won't crash
985 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
986 int lineno = iloop->lineno;
987 char *filename = iloop->filename;
988 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
995 /* if we have not been given a size */
996 if (!DCL_ELEM (type))
998 /* check, if it's a flexible array */
999 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1000 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1002 DCL_ELEM (type) = size;
1005 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1009 /*-----------------------------------------------------------------*/
1010 /* createIvalCharPtr - generates initial values for char pointers */
1011 /*-----------------------------------------------------------------*/
1013 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1018 /* if this is a pointer & right is a literal array then */
1019 /* just assignment will do */
1020 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1021 SPEC_SCLS (iexpr->etype) == S_CODE)
1022 && IS_ARRAY (iexpr->ftype)))
1023 return newNode ('=', sym, iexpr);
1025 /* left side is an array so we have to assign each */
1027 if ((IS_LITERAL (iexpr->etype) ||
1028 SPEC_SCLS (iexpr->etype) == S_CODE)
1029 && IS_ARRAY (iexpr->ftype))
1031 /* for each character generate an assignment */
1032 /* to the array element */
1033 char *s = SPEC_CVAL (iexpr->etype).v_char;
1035 unsigned int symsize = getSize (type);
1037 size = getSize (iexpr->ftype);
1038 if (symsize && size>symsize)
1040 if (size>(symsize+1))
1042 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1044 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1050 for (i=0;i<size;i++)
1052 rast = newNode (NULLOP,
1056 newAst_VALUE (valueFromLit ((float) i))),
1057 newAst_VALUE (valueFromLit (*s))));
1061 // now WE don't need iexpr's symbol anymore
1062 freeStringSymbol(AST_SYMBOL(iexpr));
1064 /* if we have not been given a size */
1065 if (!DCL_ELEM (type))
1067 /* check, if it's a flexible array */
1068 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1069 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1071 DCL_ELEM (type) = size;
1074 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1080 /*-----------------------------------------------------------------*/
1081 /* createIvalPtr - generates initial value for pointers */
1082 /*-----------------------------------------------------------------*/
1084 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1090 if (ilist->type == INIT_DEEP)
1091 ilist = ilist->init.deep;
1093 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1095 /* if character pointer */
1096 if (IS_CHAR (type->next))
1097 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1100 return newNode ('=', sym, iexpr);
1103 /*-----------------------------------------------------------------*/
1104 /* createIval - generates code for initial value */
1105 /*-----------------------------------------------------------------*/
1107 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1114 /* if structure then */
1115 if (IS_STRUCT (type))
1116 rast = createIvalStruct (sym, type, ilist, rootValue);
1118 /* if this is a pointer */
1120 rast = createIvalPtr (sym, type, ilist, rootValue);
1122 /* if this is an array */
1123 if (IS_ARRAY (type))
1124 rast = createIvalArray (sym, type, ilist, rootValue);
1126 /* if type is SPECIFIER */
1128 rast = createIvalType (sym, type, ilist);
1131 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1133 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1136 /*-----------------------------------------------------------------*/
1137 /* initAggregates - initialises aggregate variables with initv */
1138 /*-----------------------------------------------------------------*/
1139 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1140 ast *newAst = newAst_VALUE (symbolVal (sym));
1141 return createIval (newAst, sym->type, ival, wid, newAst);
1144 /*-----------------------------------------------------------------*/
1145 /* gatherAutoInit - creates assignment expressions for initial */
1147 /*-----------------------------------------------------------------*/
1149 gatherAutoInit (symbol * autoChain)
1156 for (sym = autoChain; sym; sym = sym->next)
1159 /* resolve the symbols in the ival */
1161 resolveIvalSym (sym->ival, sym->type);
1164 /* if we are PIC16 port,
1165 * and this is a static,
1166 * and have initial value,
1167 * and not S_CODE, don't emit in gs segment,
1168 * but allow glue.c:pic16emitRegularMap to put symbol
1169 * in idata section */
1170 if(TARGET_IS_PIC16 &&
1171 IS_STATIC (sym->etype) && sym->ival
1172 && SPEC_SCLS(sym->etype) != S_CODE) {
1173 SPEC_SCLS (sym->etype) = S_DATA;
1178 /* if this is a static variable & has an */
1179 /* initial value the code needs to be lifted */
1180 /* here to the main portion since they can be */
1181 /* initialised only once at the start */
1182 if (IS_STATIC (sym->etype) && sym->ival &&
1183 SPEC_SCLS (sym->etype) != S_CODE)
1187 /* insert the symbol into the symbol table */
1188 /* with level = 0 & name = rname */
1189 newSym = copySymbol (sym);
1190 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1192 /* now lift the code to main */
1193 if (IS_AGGREGATE (sym->type)) {
1194 work = initAggregates (sym, sym->ival, NULL);
1196 if (getNelements(sym->type, sym->ival)>1) {
1197 werrorfl (sym->fileDef, sym->lineDef,
1198 W_EXCESS_INITIALIZERS, "scalar",
1201 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1202 list2expr (sym->ival));
1205 setAstLineno (work, sym->lineDef);
1209 staticAutos = newNode (NULLOP, staticAutos, work);
1216 /* if there is an initial value */
1217 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1219 initList *ilist=sym->ival;
1221 while (ilist->type == INIT_DEEP) {
1222 ilist = ilist->init.deep;
1225 /* update lineno for error msg */
1226 lineno=sym->lineDef;
1227 setAstLineno (ilist->init.node, lineno);
1229 if (IS_AGGREGATE (sym->type)) {
1230 work = initAggregates (sym, sym->ival, NULL);
1232 if (getNelements(sym->type, sym->ival)>1) {
1233 werrorfl (sym->fileDef, sym->lineDef,
1234 W_EXCESS_INITIALIZERS, "scalar",
1237 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1238 list2expr (sym->ival));
1242 setAstLineno (work, sym->lineDef);
1246 init = newNode (NULLOP, init, work);
1255 /*-----------------------------------------------------------------*/
1256 /* freeStringSymbol - delete a literal string if no more usage */
1257 /*-----------------------------------------------------------------*/
1258 void freeStringSymbol(symbol *sym) {
1259 /* make sure this is a literal string */
1260 assert (sym->isstrlit);
1261 if (--sym->isstrlit == 0) { // lower the usage count
1262 memmap *segment=SPEC_OCLS(sym->etype);
1264 deleteSetItem(&segment->syms, sym);
1269 /*-----------------------------------------------------------------*/
1270 /* stringToSymbol - creates a symbol from a literal string */
1271 /*-----------------------------------------------------------------*/
1273 stringToSymbol (value * val)
1275 char name[SDCC_NAME_MAX + 1];
1276 static int charLbl = 0;
1281 // have we heard this before?
1282 for (sp=statsg->syms; sp; sp=sp->next) {
1284 size = getSize (sym->type);
1285 if (sym->isstrlit && size == getSize (val->type) &&
1286 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1287 // yes, this is old news. Don't publish it again.
1288 sym->isstrlit++; // but raise the usage count
1289 return symbolVal(sym);
1293 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1294 sym = newSymbol (name, 0); /* make it @ level 0 */
1295 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1297 /* copy the type from the value passed */
1298 sym->type = copyLinkChain (val->type);
1299 sym->etype = getSpec (sym->type);
1300 /* change to storage class & output class */
1301 SPEC_SCLS (sym->etype) = S_CODE;
1302 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1303 SPEC_STAT (sym->etype) = 1;
1304 /* make the level & block = 0 */
1305 sym->block = sym->level = 0;
1307 /* create an ival */
1308 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1313 allocVariables (sym);
1316 return symbolVal (sym);
1320 /*-----------------------------------------------------------------*/
1321 /* processBlockVars - will go thru the ast looking for block if */
1322 /* a block is found then will allocate the syms */
1323 /* will also gather the auto inits present */
1324 /*-----------------------------------------------------------------*/
1326 processBlockVars (ast * tree, int *stack, int action)
1331 /* if this is a block */
1332 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1336 if (action == ALLOCATE)
1338 *stack += allocVariables (tree->values.sym);
1339 autoInit = gatherAutoInit (tree->values.sym);
1341 /* if there are auto inits then do them */
1343 tree->left = newNode (NULLOP, autoInit, tree->left);
1345 else /* action is deallocate */
1346 deallocLocal (tree->values.sym);
1349 processBlockVars (tree->left, stack, action);
1350 processBlockVars (tree->right, stack, action);
1355 /*-------------------------------------------------------------*/
1356 /* constExprTree - returns TRUE if this tree is a constant */
1358 /*-------------------------------------------------------------*/
1359 bool constExprTree (ast *cexpr) {
1365 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1367 switch (cexpr->type)
1370 if (IS_AST_LIT_VALUE(cexpr)) {
1371 // this is a literal
1374 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1375 // a function's address will never change
1378 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1379 // an array's address will never change
1382 if (IS_AST_SYM_VALUE(cexpr) &&
1383 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1384 // a symbol in code space will never change
1385 // This is only for the 'char *s="hallo"' case and will have to leave
1386 //printf(" code space symbol");
1391 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1392 "unexpected link in expression tree\n");
1395 if (cexpr->opval.op==ARRAYINIT) {
1396 // this is a list of literals
1399 if (cexpr->opval.op=='=') {
1400 return constExprTree(cexpr->right);
1402 if (cexpr->opval.op==CAST) {
1403 // cast ignored, maybe we should throw a warning here?
1404 return constExprTree(cexpr->right);
1406 if (cexpr->opval.op=='&') {
1409 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1412 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1417 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1422 /*-----------------------------------------------------------------*/
1423 /* constExprValue - returns the value of a constant expression */
1424 /* or NULL if it is not a constant expression */
1425 /*-----------------------------------------------------------------*/
1427 constExprValue (ast * cexpr, int check)
1429 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1431 /* if this is not a constant then */
1432 if (!IS_LITERAL (cexpr->ftype))
1434 /* then check if this is a literal array
1436 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1437 SPEC_CVAL (cexpr->etype).v_char &&
1438 IS_ARRAY (cexpr->ftype))
1440 value *val = valFromType (cexpr->ftype);
1441 SPEC_SCLS (val->etype) = S_LITERAL;
1442 val->sym = cexpr->opval.val->sym;
1443 val->sym->type = copyLinkChain (cexpr->ftype);
1444 val->sym->etype = getSpec (val->sym->type);
1445 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1449 /* if we are casting a literal value then */
1450 if (IS_AST_OP (cexpr) &&
1451 cexpr->opval.op == CAST &&
1452 IS_LITERAL (cexpr->right->ftype))
1454 return valCastLiteral (cexpr->ftype,
1455 floatFromVal (cexpr->right->opval.val));
1458 if (IS_AST_VALUE (cexpr))
1460 return cexpr->opval.val;
1464 werror (E_CONST_EXPECTED, "found expression");
1469 /* return the value */
1470 if (IS_AST_VALUE (cexpr))
1472 return cexpr->opval.val;
1477 /*-----------------------------------------------------------------*/
1478 /* isLabelInAst - will return true if a given label is found */
1479 /*-----------------------------------------------------------------*/
1481 isLabelInAst (symbol * label, ast * tree)
1483 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1486 if (IS_AST_OP (tree) &&
1487 tree->opval.op == LABEL &&
1488 isSymbolEqual (AST_SYMBOL (tree->left), label))
1491 return isLabelInAst (label, tree->right) &&
1492 isLabelInAst (label, tree->left);
1496 /*-----------------------------------------------------------------*/
1497 /* isLoopCountable - return true if the loop count can be determi- */
1498 /* -ned at compile time . */
1499 /*-----------------------------------------------------------------*/
1501 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1502 symbol ** sym, ast ** init, ast ** end)
1505 /* the loop is considered countable if the following
1506 conditions are true :-
1508 a) initExpr :- <sym> = <const>
1509 b) condExpr :- <sym> < <const1>
1510 c) loopExpr :- <sym> ++
1513 /* first check the initExpr */
1514 if (IS_AST_OP (initExpr) &&
1515 initExpr->opval.op == '=' && /* is assignment */
1516 IS_AST_SYM_VALUE (initExpr->left))
1517 { /* left is a symbol */
1519 *sym = AST_SYMBOL (initExpr->left);
1520 *init = initExpr->right;
1525 /* don't reverse loop with volatile counter */
1526 if (IS_VOLATILE ((*sym)->type))
1529 /* for now the symbol has to be of
1531 if (!IS_INTEGRAL ((*sym)->type))
1534 /* now check condExpr */
1535 if (IS_AST_OP (condExpr))
1538 switch (condExpr->opval.op)
1541 if (IS_AST_SYM_VALUE (condExpr->left) &&
1542 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1543 IS_AST_LIT_VALUE (condExpr->right))
1545 *end = condExpr->right;
1551 if (IS_AST_OP (condExpr->left) &&
1552 condExpr->left->opval.op == '>' &&
1553 IS_AST_LIT_VALUE (condExpr->left->right) &&
1554 IS_AST_SYM_VALUE (condExpr->left->left) &&
1555 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1558 *end = newNode ('+', condExpr->left->right,
1559 newAst_VALUE (constVal ("1")));
1572 /* check loop expression is of the form <sym>++ */
1573 if (!IS_AST_OP (loopExpr))
1576 /* check if <sym> ++ */
1577 if (loopExpr->opval.op == INC_OP)
1583 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1584 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1591 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1592 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1600 if (loopExpr->opval.op == ADD_ASSIGN)
1603 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1604 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1605 IS_AST_LIT_VALUE (loopExpr->right) &&
1606 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1614 /*-----------------------------------------------------------------*/
1615 /* astHasVolatile - returns true if ast contains any volatile */
1616 /*-----------------------------------------------------------------*/
1618 astHasVolatile (ast * tree)
1623 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1626 if (IS_AST_OP (tree))
1627 return astHasVolatile (tree->left) ||
1628 astHasVolatile (tree->right);
1633 /*-----------------------------------------------------------------*/
1634 /* astHasPointer - return true if the ast contains any ptr variable */
1635 /*-----------------------------------------------------------------*/
1637 astHasPointer (ast * tree)
1642 if (IS_AST_LINK (tree))
1645 /* if we hit an array expression then check
1646 only the left side */
1647 if (IS_AST_OP (tree) && tree->opval.op == '[')
1648 return astHasPointer (tree->left);
1650 if (IS_AST_VALUE (tree))
1651 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1653 return astHasPointer (tree->left) ||
1654 astHasPointer (tree->right);
1658 /*-----------------------------------------------------------------*/
1659 /* astHasSymbol - return true if the ast has the given symbol */
1660 /*-----------------------------------------------------------------*/
1662 astHasSymbol (ast * tree, symbol * sym)
1664 if (!tree || IS_AST_LINK (tree))
1667 if (IS_AST_VALUE (tree))
1669 if (IS_AST_SYM_VALUE (tree))
1670 return isSymbolEqual (AST_SYMBOL (tree), sym);
1675 return astHasSymbol (tree->left, sym) ||
1676 astHasSymbol (tree->right, sym);
1679 /*-----------------------------------------------------------------*/
1680 /* astHasDeref - return true if the ast has an indirect access */
1681 /*-----------------------------------------------------------------*/
1683 astHasDeref (ast * tree)
1685 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1688 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1690 return astHasDeref (tree->left) || astHasDeref (tree->right);
1693 /*-----------------------------------------------------------------*/
1694 /* isConformingBody - the loop body has to conform to a set of rules */
1695 /* for the loop to be considered reversible read on for rules */
1696 /*-----------------------------------------------------------------*/
1698 isConformingBody (ast * pbody, symbol * sym, ast * body)
1701 /* we are going to do a pre-order traversal of the
1702 tree && check for the following conditions. (essentially
1703 a set of very shallow tests )
1704 a) the sym passed does not participate in
1705 any arithmetic operation
1706 b) There are no function calls
1707 c) all jumps are within the body
1708 d) address of loop control variable not taken
1709 e) if an assignment has a pointer on the
1710 left hand side make sure right does not have
1711 loop control variable */
1713 /* if we reach the end or a leaf then true */
1714 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1717 /* if anything else is "volatile" */
1718 if (IS_VOLATILE (TETYPE (pbody)))
1721 /* we will walk the body in a pre-order traversal for
1723 switch (pbody->opval.op)
1725 /*------------------------------------------------------------------*/
1727 // if the loopvar is used as an index
1728 /* array op is commutative -- must check both left & right */
1729 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1732 return isConformingBody (pbody->right, sym, body)
1733 && isConformingBody (pbody->left, sym, body);
1735 /*------------------------------------------------------------------*/
1740 /*------------------------------------------------------------------*/
1744 /* sure we are not sym is not modified */
1746 IS_AST_SYM_VALUE (pbody->left) &&
1747 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1751 IS_AST_SYM_VALUE (pbody->right) &&
1752 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1757 /*------------------------------------------------------------------*/
1759 case '*': /* can be unary : if right is null then unary operation */
1764 /* if right is NULL then unary operation */
1765 /*------------------------------------------------------------------*/
1766 /*----------------------------*/
1768 /*----------------------------*/
1771 if (IS_AST_SYM_VALUE (pbody->left) &&
1772 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1775 return isConformingBody (pbody->left, sym, body);
1779 if (astHasSymbol (pbody->left, sym) ||
1780 astHasSymbol (pbody->right, sym))
1785 /*------------------------------------------------------------------*/
1796 if (IS_AST_SYM_VALUE (pbody->left) &&
1797 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1800 if (IS_AST_SYM_VALUE (pbody->right) &&
1801 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1804 return isConformingBody (pbody->left, sym, body) &&
1805 isConformingBody (pbody->right, sym, body);
1813 if (IS_AST_SYM_VALUE (pbody->left) &&
1814 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1816 return isConformingBody (pbody->left, sym, body);
1818 /*------------------------------------------------------------------*/
1830 case SIZEOF: /* evaluate wihout code generation */
1832 if (IS_AST_SYM_VALUE (pbody->left) &&
1833 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1836 if (IS_AST_SYM_VALUE (pbody->right) &&
1837 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1840 return isConformingBody (pbody->left, sym, body) &&
1841 isConformingBody (pbody->right, sym, body);
1843 /*------------------------------------------------------------------*/
1846 /* if left has a pointer & right has loop
1847 control variable then we cannot */
1848 if (astHasPointer (pbody->left) &&
1849 astHasSymbol (pbody->right, sym))
1851 if (astHasVolatile (pbody->left))
1854 if (IS_AST_SYM_VALUE (pbody->left)) {
1855 // if the loopvar has an assignment
1856 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1858 // if the loopvar is used in another (maybe conditional) block
1859 if (astHasSymbol (pbody->right, sym) &&
1860 (pbody->level >= body->level)) {
1865 if (astHasVolatile (pbody->left))
1868 if (astHasDeref(pbody->right)) return FALSE;
1870 return isConformingBody (pbody->left, sym, body) &&
1871 isConformingBody (pbody->right, sym, body);
1882 assert ("Parser should not have generated this\n");
1884 /*------------------------------------------------------------------*/
1885 /*----------------------------*/
1886 /* comma operator */
1887 /*----------------------------*/
1889 return isConformingBody (pbody->left, sym, body) &&
1890 isConformingBody (pbody->right, sym, body);
1892 /*------------------------------------------------------------------*/
1893 /*----------------------------*/
1895 /*----------------------------*/
1897 /* if local & not passed as paramater then ok */
1898 if (sym->level && !astHasSymbol(pbody->right,sym))
1902 /*------------------------------------------------------------------*/
1903 /*----------------------------*/
1904 /* return statement */
1905 /*----------------------------*/
1910 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1915 if (astHasSymbol (pbody->left, sym))
1922 return isConformingBody (pbody->left, sym, body) &&
1923 isConformingBody (pbody->right, sym, body);
1929 /*-----------------------------------------------------------------*/
1930 /* isLoopReversible - takes a for loop as input && returns true */
1931 /* if the for loop is reversible. If yes will set the value of */
1932 /* the loop control var & init value & termination value */
1933 /*-----------------------------------------------------------------*/
1935 isLoopReversible (ast * loop, symbol ** loopCntrl,
1936 ast ** init, ast ** end)
1938 /* if option says don't do it then don't */
1939 if (optimize.noLoopReverse)
1941 /* there are several tests to determine this */
1943 /* for loop has to be of the form
1944 for ( <sym> = <const1> ;
1945 [<sym> < <const2>] ;
1946 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1948 if (!isLoopCountable (AST_FOR (loop, initExpr),
1949 AST_FOR (loop, condExpr),
1950 AST_FOR (loop, loopExpr),
1951 loopCntrl, init, end))
1954 /* now do some serious checking on the body of the loop
1957 return isConformingBody (loop->left, *loopCntrl, loop->left);
1961 /*-----------------------------------------------------------------*/
1962 /* replLoopSym - replace the loop sym by loop sym -1 */
1963 /*-----------------------------------------------------------------*/
1965 replLoopSym (ast * body, symbol * sym)
1968 if (!body || IS_AST_LINK (body))
1971 if (IS_AST_SYM_VALUE (body))
1974 if (isSymbolEqual (AST_SYMBOL (body), sym))
1978 body->opval.op = '-';
1979 body->left = newAst_VALUE (symbolVal (sym));
1980 body->right = newAst_VALUE (constVal ("1"));
1988 replLoopSym (body->left, sym);
1989 replLoopSym (body->right, sym);
1993 /*-----------------------------------------------------------------*/
1994 /* reverseLoop - do the actual loop reversal */
1995 /*-----------------------------------------------------------------*/
1997 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
2001 /* create the following tree
2006 if (sym) goto for_continue ;
2009 /* put it together piece by piece */
2010 rloop = newNode (NULLOP,
2011 createIf (newAst_VALUE (symbolVal (sym)),
2013 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2016 newAst_VALUE (symbolVal (sym)),
2019 replLoopSym (loop->left, sym);
2020 setAstLineno (rloop, init->lineno);
2022 rloop = newNode (NULLOP,
2024 newAst_VALUE (symbolVal (sym)),
2025 newNode ('-', end, init)),
2026 createLabel (AST_FOR (loop, continueLabel),
2030 newNode (SUB_ASSIGN,
2031 newAst_VALUE (symbolVal (sym)),
2032 newAst_VALUE (constVal ("1"))),
2035 rloop->lineno=init->lineno;
2036 return decorateType (rloop, RESULT_TYPE_NONE);
2040 /*-----------------------------------------------------------------*/
2041 /* searchLitOp - search tree (*ops only) for an ast with literal */
2042 /*-----------------------------------------------------------------*/
2044 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2048 if (tree && optimize.global_cse)
2050 /* is there a literal operand? */
2052 IS_AST_OP(tree->right) &&
2053 tree->right->right &&
2054 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2056 if (IS_LITERAL (RTYPE (tree->right)) !=
2057 IS_LITERAL (LTYPE (tree->right)))
2059 tree->right->decorated = 0;
2060 tree->decorated = 0;
2064 ret = searchLitOp (tree->right, parent, ops);
2069 IS_AST_OP(tree->left) &&
2070 tree->left->right &&
2071 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2073 if (IS_LITERAL (RTYPE (tree->left)) !=
2074 IS_LITERAL (LTYPE (tree->left)))
2076 tree->left->decorated = 0;
2077 tree->decorated = 0;
2081 ret = searchLitOp (tree->left, parent, ops);
2089 /*-----------------------------------------------------------------*/
2090 /* getResultFromType */
2091 /*-----------------------------------------------------------------*/
2093 getResultTypeFromType (sym_link *type)
2095 /* type = getSpec (type); */
2097 return RESULT_TYPE_BIT;
2098 if (IS_BITFIELD (type))
2100 int blen = SPEC_BLEN (type);
2103 return RESULT_TYPE_BIT;
2105 return RESULT_TYPE_CHAR;
2106 return RESULT_TYPE_INT;
2109 return RESULT_TYPE_CHAR;
2112 return RESULT_TYPE_INT;
2113 return RESULT_TYPE_OTHER;
2116 /*-----------------------------------------------------------------*/
2117 /* addCast - adds casts to a type specified by RESULT_TYPE */
2118 /*-----------------------------------------------------------------*/
2120 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2123 bool upCasted = FALSE;
2127 case RESULT_TYPE_NONE:
2128 /* if thing smaller than int must be promoted to int */
2130 getSize (tree->etype) >= INTSIZE)
2131 /* promotion not necessary or already an int */
2133 /* char and bits: promote to int */
2134 newLink = newIntLink();
2137 case RESULT_TYPE_BIT:
2139 /* already an int */
2140 bitsForType (tree->etype) >= 16 ||
2141 /* bit to bit operation: don't promote, the code generators
2142 hopefully know everything about promotion rules */
2143 bitsForType (tree->etype) == 1)
2145 newLink = newIntLink();
2148 case RESULT_TYPE_CHAR:
2149 if (IS_CHAR (tree->etype) ||
2150 IS_FLOAT(tree->etype) ||
2151 IS_FIXED(tree->etype))
2153 newLink = newCharLink();
2155 case RESULT_TYPE_INT:
2157 if (getSize (tree->etype) > INTSIZE)
2159 /* warn ("Loosing significant digits"); */
2163 /* char: promote to int */
2165 getSize (tree->etype) >= INTSIZE)
2167 newLink = newIntLink();
2170 case RESULT_TYPE_OTHER:
2173 /* return type is long, float: promote char to int */
2174 if (getSize (tree->etype) >= INTSIZE)
2176 newLink = newIntLink();
2182 tree->decorated = 0;
2183 tree = newNode (CAST, newAst_LINK (newLink), tree);
2184 tree->lineno = tree->right->lineno;
2185 /* keep unsigned type during cast to smaller type,
2186 but not when promoting from char to int */
2188 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2189 return decorateType (tree, resultType);
2192 /*-----------------------------------------------------------------*/
2193 /* resultTypePropagate - decides if resultType can be propagated */
2194 /*-----------------------------------------------------------------*/
2196 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2198 switch (tree->opval.op)
2217 return RESULT_TYPE_NONE;
2221 return RESULT_TYPE_IFX;
2223 return RESULT_TYPE_NONE;
2227 /*-----------------------------------------------------------------*/
2228 /* getLeftResultType - gets type from left branch for propagation */
2229 /*-----------------------------------------------------------------*/
2231 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2233 switch (tree->opval.op)
2237 if (IS_PTR (LTYPE (tree)))
2238 return RESULT_TYPE_NONE;
2240 return getResultTypeFromType (LETYPE (tree));
2242 if (IS_PTR (currFunc->type->next))
2243 return RESULT_TYPE_NONE;
2245 return getResultTypeFromType (currFunc->type->next);
2247 if (!IS_ARRAY (LTYPE (tree)))
2249 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2250 return RESULT_TYPE_CHAR;
2257 /*--------------------------------------------------------------------*/
2258 /* decorateType - compute type for this tree, also does type checking.*/
2259 /* This is done bottom up, since type has to flow upwards. */
2260 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2261 /* result is a char and the operand(s) are int's. */
2262 /* It also does constant folding, and parameter checking. */
2263 /*--------------------------------------------------------------------*/
2265 decorateType (ast * tree, RESULT_TYPE resultType)
2269 RESULT_TYPE resultTypeProp;
2274 /* if already has type then do nothing */
2275 if (tree->decorated)
2278 tree->decorated = 1;
2281 /* print the line */
2282 /* if not block & function */
2283 if (tree->type == EX_OP &&
2284 (tree->opval.op != FUNCTION &&
2285 tree->opval.op != BLOCK &&
2286 tree->opval.op != NULLOP))
2288 filename = tree->filename;
2289 lineno = tree->lineno;
2293 /* if any child is an error | this one is an error do nothing */
2294 if (tree->isError ||
2295 (tree->left && tree->left->isError) ||
2296 (tree->right && tree->right->isError))
2299 /*------------------------------------------------------------------*/
2300 /*----------------------------*/
2301 /* leaf has been reached */
2302 /*----------------------------*/
2303 lineno=tree->lineno;
2304 /* if this is of type value */
2305 /* just get the type */
2306 if (tree->type == EX_VALUE)
2309 if (IS_LITERAL (tree->opval.val->etype))
2312 /* if this is a character array then declare it */
2313 if (IS_ARRAY (tree->opval.val->type))
2314 tree->opval.val = stringToSymbol (tree->opval.val);
2316 /* otherwise just copy the type information */
2317 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2321 if (tree->opval.val->sym)
2323 /* if the undefined flag is set then give error message */
2324 if (tree->opval.val->sym->undefined)
2326 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2328 TTYPE (tree) = TETYPE (tree) =
2329 tree->opval.val->type = tree->opval.val->sym->type =
2330 tree->opval.val->etype = tree->opval.val->sym->etype =
2331 copyLinkChain (INTTYPE);
2336 /* if impilicit i.e. struct/union member then no type */
2337 if (tree->opval.val->sym->implicit)
2338 TTYPE (tree) = TETYPE (tree) = NULL;
2343 /* else copy the type */
2344 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2346 /* and mark it as referenced */
2347 tree->opval.val->sym->isref = 1;
2355 /* if type link for the case of cast */
2356 if (tree->type == EX_LINK)
2358 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2366 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2368 if (tree->left && tree->left->type == EX_OPERAND
2369 && (tree->left->opval.op == INC_OP
2370 || tree->left->opval.op == DEC_OP)
2371 && tree->left->left)
2373 tree->left->right = tree->left->left;
2374 tree->left->left = NULL;
2376 if (tree->right && tree->right->type == EX_OPERAND
2377 && (tree->right->opval.op == INC_OP
2378 || tree->right->opval.op == DEC_OP)
2379 && tree->right->left)
2381 tree->right->right = tree->right->left;
2382 tree->right->left = NULL;
2387 /* Before decorating the left branch we've to decide in dependence
2388 upon tree->opval.op, if resultType can be propagated */
2389 resultTypeProp = resultTypePropagate (tree, resultType);
2391 if (tree->opval.op == '?')
2392 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2394 dtl = decorateType (tree->left, resultTypeProp);
2396 /* if an array node, we may need to swap branches */
2397 if (tree->opval.op == '[')
2399 /* determine which is the array & which the index */
2400 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2401 IS_INTEGRAL (LTYPE (tree)))
2403 ast *tempTree = tree->left;
2404 tree->left = tree->right;
2405 tree->right = tempTree;
2409 /* After decorating the left branch there's type information available
2410 in tree->left->?type. If the op is e.g. '=' we extract the type
2411 information from there and propagate it to the right branch. */
2412 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2414 switch (tree->opval.op)
2417 /* delay right side for '?' operator since conditional macro
2418 expansions might rely on this */
2422 /* decorate right side for CALL (parameter list) in processParms();
2423 there is resultType available */
2427 dtr = decorateType (tree->right, resultTypeProp);
2431 /* this is to take care of situations
2432 when the tree gets rewritten */
2433 if (dtl != tree->left)
2435 if (dtr != tree->right)
2437 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2441 /* depending on type of operator do */
2443 switch (tree->opval.op)
2445 /*------------------------------------------------------------------*/
2446 /*----------------------------*/
2448 /*----------------------------*/
2451 /* first check if this is a array or a pointer */
2452 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2454 werror (E_NEED_ARRAY_PTR, "[]");
2455 goto errorTreeReturn;
2458 /* check if the type of the idx */
2459 if (!IS_INTEGRAL (RTYPE (tree)))
2461 werror (E_IDX_NOT_INT);
2462 goto errorTreeReturn;
2465 /* if the left is an rvalue then error */
2468 werror (E_LVALUE_REQUIRED, "array access");
2469 goto errorTreeReturn;
2472 if (IS_LITERAL (RTYPE (tree)))
2474 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2475 int arraySize = DCL_ELEM (LTYPE (tree));
2476 if (arraySize && arrayIndex >= arraySize)
2478 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2483 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2484 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2487 /*------------------------------------------------------------------*/
2488 /*----------------------------*/
2490 /*----------------------------*/
2492 /* if this is not a structure */
2493 if (!IS_STRUCT (LTYPE (tree)))
2495 werror (E_STRUCT_UNION, ".");
2496 goto errorTreeReturn;
2498 TTYPE (tree) = structElemType (LTYPE (tree),
2499 (tree->right->type == EX_VALUE ?
2500 tree->right->opval.val : NULL));
2501 TETYPE (tree) = getSpec (TTYPE (tree));
2504 /*------------------------------------------------------------------*/
2505 /*----------------------------*/
2506 /* struct/union pointer */
2507 /*----------------------------*/
2509 /* if not pointer to a structure */
2510 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2512 werror (E_PTR_REQD);
2513 goto errorTreeReturn;
2516 if (!IS_STRUCT (LTYPE (tree)->next))
2518 werror (E_STRUCT_UNION, "->");
2519 goto errorTreeReturn;
2522 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2523 (tree->right->type == EX_VALUE ?
2524 tree->right->opval.val : NULL));
2525 TETYPE (tree) = getSpec (TTYPE (tree));
2527 /* adjust the storage class */
2528 switch (DCL_TYPE(tree->left->ftype)) {
2530 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2533 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2536 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2539 SPEC_SCLS (TETYPE (tree)) = 0;
2542 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2545 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2548 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2551 SPEC_SCLS (TETYPE (tree)) = 0;
2558 /* This breaks with extern declarations, bitfields, and perhaps other */
2559 /* cases (gcse). Let's leave this optimization disabled for now and */
2560 /* ponder if there's a safe way to do this. -- EEP */
2562 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2563 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2565 /* If defined struct type at addr var
2566 then rewrite (&struct var)->member
2568 and define membertype at (addr+offsetof(struct var,member)) temp
2571 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2572 AST_SYMBOL(tree->right));
2574 sym = newSymbol(genSymName (0), 0);
2575 sym->type = TTYPE (tree);
2576 sym->etype = getSpec(sym->type);
2577 sym->lineDef = tree->lineno;
2580 SPEC_STAT (sym->etype) = 1;
2581 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2583 SPEC_ABSA(sym->etype) = 1;
2584 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2587 AST_VALUE (tree) = symbolVal(sym);
2590 tree->type = EX_VALUE;
2598 /*------------------------------------------------------------------*/
2599 /*----------------------------*/
2600 /* ++/-- operation */
2601 /*----------------------------*/
2605 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2606 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2607 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2608 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2617 /*------------------------------------------------------------------*/
2618 /*----------------------------*/
2620 /*----------------------------*/
2621 case '&': /* can be unary */
2622 /* if right is NULL then unary operation */
2623 if (tree->right) /* not an unary operation */
2626 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2628 werror (E_BITWISE_OP);
2629 werror (W_CONTINUE, "left & right types are ");
2630 printTypeChain (LTYPE (tree), stderr);
2631 fprintf (stderr, ",");
2632 printTypeChain (RTYPE (tree), stderr);
2633 fprintf (stderr, "\n");
2634 goto errorTreeReturn;
2637 /* if they are both literal */
2638 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2640 tree->type = EX_VALUE;
2641 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2642 valFromType (RETYPE (tree)), '&');
2644 tree->right = tree->left = NULL;
2645 TETYPE (tree) = tree->opval.val->etype;
2646 TTYPE (tree) = tree->opval.val->type;
2650 /* see if this is a GETHBIT operation if yes
2653 ast *otree = optimizeGetHbit (tree, resultType);
2656 return decorateType (otree, RESULT_TYPE_NONE);
2659 /* see if this is a GETABIT operation if yes
2662 ast *otree = optimizeGetAbit (tree, resultType);
2665 return decorateType (otree, RESULT_TYPE_NONE);
2668 /* see if this is a GETBYTE operation if yes
2671 ast *otree = optimizeGetByte (tree, resultType);
2674 return decorateType (otree, RESULT_TYPE_NONE);
2677 /* see if this is a GETWORD operation if yes
2680 ast *otree = optimizeGetWord (tree, resultType);
2683 return decorateType (otree, RESULT_TYPE_NONE);
2686 /* if left is a literal exchange left & right */
2687 if (IS_LITERAL (LTYPE (tree)))
2689 ast *tTree = tree->left;
2690 tree->left = tree->right;
2691 tree->right = tTree;
2694 /* if right is a literal and */
2695 /* we can find a 2nd literal in an and-tree then */
2696 /* rearrange the tree */
2697 if (IS_LITERAL (RTYPE (tree)))
2700 ast *litTree = searchLitOp (tree, &parent, "&");
2704 ast *tTree = litTree->left;
2705 litTree->left = tree->right;
2706 tree->right = tTree;
2707 /* both operands in litTree are literal now */
2708 decorateType (parent, resultType);
2712 LRVAL (tree) = RRVAL (tree) = 1;
2714 TTYPE (tree) = computeType (LTYPE (tree),
2718 TETYPE (tree) = getSpec (TTYPE (tree));
2723 /*------------------------------------------------------------------*/
2724 /*----------------------------*/
2726 /*----------------------------*/
2727 p = newLink (DECLARATOR);
2728 /* if bit field then error */
2729 if (IS_BITVAR (tree->left->etype))
2731 werror (E_ILLEGAL_ADDR, "address of bit variable");
2732 goto errorTreeReturn;
2735 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2737 werror (E_ILLEGAL_ADDR, "address of register variable");
2738 goto errorTreeReturn;
2741 if (IS_FUNC (LTYPE (tree)))
2743 // this ought to be ignored
2744 return (tree->left);
2747 if (IS_LITERAL(LTYPE(tree)))
2749 werror (E_ILLEGAL_ADDR, "address of literal");
2750 goto errorTreeReturn;
2755 werror (E_LVALUE_REQUIRED, "address of");
2756 goto errorTreeReturn;
2759 DCL_TYPE (p) = POINTER;
2760 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2761 DCL_TYPE (p) = CPOINTER;
2762 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2763 DCL_TYPE (p) = FPOINTER;
2764 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2765 DCL_TYPE (p) = PPOINTER;
2766 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2767 DCL_TYPE (p) = IPOINTER;
2768 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2769 DCL_TYPE (p) = EEPPOINTER;
2770 else if (SPEC_OCLS(tree->left->etype))
2771 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2773 DCL_TYPE (p) = POINTER;
2775 if (IS_AST_SYM_VALUE (tree->left))
2777 AST_SYMBOL (tree->left)->addrtaken = 1;
2778 AST_SYMBOL (tree->left)->allocreq = 1;
2781 p->next = LTYPE (tree);
2783 TETYPE (tree) = getSpec (TTYPE (tree));
2788 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2789 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2791 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2792 AST_SYMBOL(tree->left->right));
2793 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2794 valueFromLit(element->offset));
2797 tree->type = EX_VALUE;
2798 tree->values.literalFromCast = 1;
2804 /*------------------------------------------------------------------*/
2805 /*----------------------------*/
2807 /*----------------------------*/
2809 /* if the rewrite succeeds then don't go any further */
2811 ast *wtree = optimizeRRCRLC (tree);
2813 return decorateType (wtree, RESULT_TYPE_NONE);
2815 wtree = optimizeSWAP (tree);
2817 return decorateType (wtree, RESULT_TYPE_NONE);
2820 /* if left is a literal exchange left & right */
2821 if (IS_LITERAL (LTYPE (tree)))
2823 ast *tTree = tree->left;
2824 tree->left = tree->right;
2825 tree->right = tTree;
2828 /* if right is a literal and */
2829 /* we can find a 2nd literal in an or-tree then */
2830 /* rearrange the tree */
2831 if (IS_LITERAL (RTYPE (tree)))
2834 ast *litTree = searchLitOp (tree, &parent, "|");
2838 ast *tTree = litTree->left;
2839 litTree->left = tree->right;
2840 tree->right = tTree;
2841 /* both operands in tTree are literal now */
2842 decorateType (parent, resultType);
2847 /*------------------------------------------------------------------*/
2848 /*----------------------------*/
2850 /*----------------------------*/
2852 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2854 werror (E_BITWISE_OP);
2855 werror (W_CONTINUE, "left & right types are ");
2856 printTypeChain (LTYPE (tree), stderr);
2857 fprintf (stderr, ",");
2858 printTypeChain (RTYPE (tree), stderr);
2859 fprintf (stderr, "\n");
2860 goto errorTreeReturn;
2863 /* if they are both literal then rewrite the tree */
2864 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2866 tree->type = EX_VALUE;
2867 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2868 valFromType (RETYPE (tree)),
2870 tree->right = tree->left = NULL;
2871 TETYPE (tree) = tree->opval.val->etype;
2872 TTYPE (tree) = tree->opval.val->type;
2876 /* if left is a literal exchange left & right */
2877 if (IS_LITERAL (LTYPE (tree)))
2879 ast *tTree = tree->left;
2880 tree->left = tree->right;
2881 tree->right = tTree;
2884 /* if right is a literal and */
2885 /* we can find a 2nd literal in a xor-tree then */
2886 /* rearrange the tree */
2887 if (IS_LITERAL (RTYPE (tree)) &&
2888 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2891 ast *litTree = searchLitOp (tree, &parent, "^");
2895 ast *tTree = litTree->left;
2896 litTree->left = tree->right;
2897 tree->right = tTree;
2898 /* both operands in litTree are literal now */
2899 decorateType (parent, resultType);
2903 LRVAL (tree) = RRVAL (tree) = 1;
2905 TTYPE (tree) = computeType (LTYPE (tree),
2909 TETYPE (tree) = getSpec (TTYPE (tree));
2913 /*------------------------------------------------------------------*/
2914 /*----------------------------*/
2916 /*----------------------------*/
2918 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2920 werror (E_INVALID_OP, "divide");
2921 goto errorTreeReturn;
2923 /* if they are both literal then */
2924 /* rewrite the tree */
2925 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2927 tree->type = EX_VALUE;
2928 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2929 valFromType (RETYPE (tree)));
2930 tree->right = tree->left = NULL;
2931 TETYPE (tree) = getSpec (TTYPE (tree) =
2932 tree->opval.val->type);
2936 LRVAL (tree) = RRVAL (tree) = 1;
2938 TETYPE (tree) = getSpec (TTYPE (tree) =
2939 computeType (LTYPE (tree),
2944 /* if right is a literal and */
2945 /* left is also a division by a literal then */
2946 /* rearrange the tree */
2947 if (IS_LITERAL (RTYPE (tree))
2948 /* avoid infinite loop */
2949 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2952 ast *litTree = searchLitOp (tree, &parent, "/");
2955 if (IS_LITERAL (RTYPE (litTree)))
2959 litTree->right = newNode ('*',
2961 copyAst (tree->right));
2962 litTree->right->lineno = tree->lineno;
2964 tree->right->opval.val = constVal ("1");
2965 decorateType (parent, resultType);
2969 /* litTree->left is literal: no gcse possible.
2970 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2971 this would cause an infinit loop. */
2972 parent->decorated = 1;
2973 decorateType (litTree, resultType);
2980 /*------------------------------------------------------------------*/
2981 /*----------------------------*/
2983 /*----------------------------*/
2985 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2987 werror (E_BITWISE_OP);
2988 werror (W_CONTINUE, "left & right types are ");
2989 printTypeChain (LTYPE (tree), stderr);
2990 fprintf (stderr, ",");
2991 printTypeChain (RTYPE (tree), stderr);
2992 fprintf (stderr, "\n");
2993 goto errorTreeReturn;
2995 /* if they are both literal then */
2996 /* rewrite the tree */
2997 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2999 tree->type = EX_VALUE;
3000 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3001 valFromType (RETYPE (tree)));
3002 tree->right = tree->left = NULL;
3003 TETYPE (tree) = getSpec (TTYPE (tree) =
3004 tree->opval.val->type);
3007 LRVAL (tree) = RRVAL (tree) = 1;
3008 TETYPE (tree) = getSpec (TTYPE (tree) =
3009 computeType (LTYPE (tree),
3015 /*------------------------------------------------------------------*/
3016 /*----------------------------*/
3017 /* address dereference */
3018 /*----------------------------*/
3019 case '*': /* can be unary : if right is null then unary operation */
3022 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3024 werror (E_PTR_REQD);
3025 goto errorTreeReturn;
3030 werror (E_LVALUE_REQUIRED, "pointer deref");
3031 goto errorTreeReturn;
3033 if (IS_ADDRESS_OF_OP(tree->left))
3035 /* replace *&obj with obj */
3036 return tree->left->left;
3038 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3039 TETYPE (tree) = getSpec (TTYPE (tree));
3040 /* adjust the storage class */
3041 switch (DCL_TYPE(tree->left->ftype)) {
3043 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3046 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3049 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3052 SPEC_SCLS (TETYPE (tree)) = 0;
3055 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3058 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3061 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3064 SPEC_SCLS (TETYPE (tree)) = 0;
3073 /*------------------------------------------------------------------*/
3074 /*----------------------------*/
3075 /* multiplication */
3076 /*----------------------------*/
3077 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3079 werror (E_INVALID_OP, "multiplication");
3080 goto errorTreeReturn;
3083 /* if they are both literal then */
3084 /* rewrite the tree */
3085 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3087 tree->type = EX_VALUE;
3088 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3089 valFromType (RETYPE (tree)));
3090 tree->right = tree->left = NULL;
3091 TETYPE (tree) = getSpec (TTYPE (tree) =
3092 tree->opval.val->type);
3096 /* if left is a literal exchange left & right */
3097 if (IS_LITERAL (LTYPE (tree)))
3099 ast *tTree = tree->left;
3100 tree->left = tree->right;
3101 tree->right = tTree;
3104 /* if right is a literal and */
3105 /* we can find a 2nd literal in a mul-tree then */
3106 /* rearrange the tree */
3107 if (IS_LITERAL (RTYPE (tree)))
3110 ast *litTree = searchLitOp (tree, &parent, "*");
3114 ast *tTree = litTree->left;
3115 litTree->left = tree->right;
3116 tree->right = tTree;
3117 /* both operands in litTree are literal now */
3118 decorateType (parent, resultType);
3122 LRVAL (tree) = RRVAL (tree) = 1;
3123 tree->left = addCast (tree->left, resultType, FALSE);
3124 tree->right = addCast (tree->right, resultType, FALSE);
3125 TETYPE (tree) = getSpec (TTYPE (tree) =
3126 computeType (LTYPE (tree),
3133 /*------------------------------------------------------------------*/
3134 /*----------------------------*/
3135 /* unary '+' operator */
3136 /*----------------------------*/
3141 if (!IS_ARITHMETIC (LTYPE (tree)))
3143 werror (E_UNARY_OP, '+');
3144 goto errorTreeReturn;
3147 /* if left is a literal then do it */
3148 if (IS_LITERAL (LTYPE (tree)))
3150 tree->type = EX_VALUE;
3151 tree->opval.val = valFromType (LETYPE (tree));
3153 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3157 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3164 /*----------------------------*/
3166 /* this is not a unary operation */
3167 /* if both pointers then problem */
3168 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3169 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3171 werror (E_PTR_PLUS_PTR);
3172 goto errorTreeReturn;
3175 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3176 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3178 werror (E_PLUS_INVALID, "+");
3179 goto errorTreeReturn;
3182 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3183 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3185 werror (E_PLUS_INVALID, "+");
3186 goto errorTreeReturn;
3188 /* if they are both literal then */
3189 /* rewrite the tree */
3190 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3192 tree->type = EX_VALUE;
3193 tree->left = addCast (tree->left, resultType, TRUE);
3194 tree->right = addCast (tree->right, resultType, TRUE);
3195 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3196 valFromType (RETYPE (tree)));
3197 tree->right = tree->left = NULL;
3198 TETYPE (tree) = getSpec (TTYPE (tree) =
3199 tree->opval.val->type);
3203 /* if the right is a pointer or left is a literal
3204 xchange left & right */
3205 if (IS_ARRAY (RTYPE (tree)) ||
3206 IS_PTR (RTYPE (tree)) ||
3207 IS_LITERAL (LTYPE (tree)))
3209 ast *tTree = tree->left;
3210 tree->left = tree->right;
3211 tree->right = tTree;
3214 /* if right is a literal and */
3215 /* left is also an addition/subtraction with a literal then */
3216 /* rearrange the tree */
3217 if (IS_LITERAL (RTYPE (tree)))
3219 ast *litTree, *parent;
3220 litTree = searchLitOp (tree, &parent, "+-");
3223 if (litTree->opval.op == '+')
3227 ast *tTree = litTree->left;
3228 litTree->left = tree->right;
3229 tree->right = tree->left;
3232 else if (litTree->opval.op == '-')
3234 if (IS_LITERAL (RTYPE (litTree)))
3238 ast *tTree = litTree->left;
3239 litTree->left = tree->right;
3240 tree->right = tTree;
3246 ast *tTree = litTree->right;
3247 litTree->right = tree->right;
3248 tree->right = tTree;
3249 litTree->opval.op = '+';
3250 tree->opval.op = '-';
3253 decorateType (parent, resultType);
3257 LRVAL (tree) = RRVAL (tree) = 1;
3258 /* if the left is a pointer */
3259 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3260 TETYPE (tree) = getSpec (TTYPE (tree) =
3264 tree->left = addCast (tree->left, resultType, TRUE);
3265 tree->right = addCast (tree->right, resultType, TRUE);
3266 TETYPE (tree) = getSpec (TTYPE (tree) =
3267 computeType (LTYPE (tree),
3275 /*------------------------------------------------------------------*/
3276 /*----------------------------*/
3278 /*----------------------------*/
3279 case '-': /* can be unary */
3280 /* if right is null then unary */
3284 if (!IS_ARITHMETIC (LTYPE (tree)))
3286 werror (E_UNARY_OP, tree->opval.op);
3287 goto errorTreeReturn;
3290 /* if left is a literal then do it */
3291 if (IS_LITERAL (LTYPE (tree)))
3293 tree->type = EX_VALUE;
3294 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3296 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3299 tree->left = addCast (tree->left, resultType, TRUE);
3300 TETYPE (tree) = getSpec (TTYPE (tree) =
3301 computeType (LTYPE (tree),
3309 /*------------------------------------------------------------------*/
3310 /*----------------------------*/
3312 /*----------------------------*/
3314 if (!(IS_PTR (LTYPE (tree)) ||
3315 IS_ARRAY (LTYPE (tree)) ||
3316 IS_ARITHMETIC (LTYPE (tree))))
3318 werror (E_PLUS_INVALID, "-");
3319 goto errorTreeReturn;
3322 if (!(IS_PTR (RTYPE (tree)) ||
3323 IS_ARRAY (RTYPE (tree)) ||
3324 IS_ARITHMETIC (RTYPE (tree))))
3326 werror (E_PLUS_INVALID, "-");
3327 goto errorTreeReturn;
3330 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3331 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3332 IS_INTEGRAL (RTYPE (tree))))
3334 werror (E_PLUS_INVALID, "-");
3335 goto errorTreeReturn;
3338 /* if they are both literal then */
3339 /* rewrite the tree */
3340 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3342 tree->type = EX_VALUE;
3343 tree->left = addCast (tree->left, resultType, TRUE);
3344 tree->right = addCast (tree->right, resultType, TRUE);
3345 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3346 valFromType (RETYPE (tree)));
3347 tree->right = tree->left = NULL;
3348 TETYPE (tree) = getSpec (TTYPE (tree) =
3349 tree->opval.val->type);
3353 /* if the left & right are equal then zero */
3354 if (isAstEqual (tree->left, tree->right))
3356 tree->type = EX_VALUE;
3357 tree->left = tree->right = NULL;
3358 tree->opval.val = constVal ("0");
3359 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3363 /* if both of them are pointers or arrays then */
3364 /* the result is going to be an integer */
3365 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3366 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3367 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3369 /* if only the left is a pointer */
3370 /* then result is a pointer */
3371 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3372 TETYPE (tree) = getSpec (TTYPE (tree) =
3376 tree->left = addCast (tree->left, resultType, TRUE);
3377 tree->right = addCast (tree->right, resultType, TRUE);
3379 TETYPE (tree) = getSpec (TTYPE (tree) =
3380 computeType (LTYPE (tree),
3386 LRVAL (tree) = RRVAL (tree) = 1;
3388 /* if right is a literal and */
3389 /* left is also an addition/subtraction with a literal then */
3390 /* rearrange the tree */
3391 if (IS_LITERAL (RTYPE (tree))
3392 /* avoid infinite loop */
3393 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3395 ast *litTree, *litParent;
3396 litTree = searchLitOp (tree, &litParent, "+-");
3399 if (litTree->opval.op == '+')
3403 ast *tTree = litTree->left;
3404 litTree->left = litTree->right;
3405 litTree->right = tree->right;
3406 tree->right = tTree;
3407 tree->opval.op = '+';
3408 litTree->opval.op = '-';
3410 else if (litTree->opval.op == '-')
3412 if (IS_LITERAL (RTYPE (litTree)))
3416 ast *tTree = litTree->left;
3417 litTree->left = tree->right;
3418 tree->right = litParent->left;
3419 litParent->left = tTree;
3420 litTree->opval.op = '+';
3422 tree->decorated = 0;
3423 decorateType (tree, resultType);
3429 ast *tTree = litTree->right;
3430 litTree->right = tree->right;
3431 tree->right = tTree;
3434 decorateType (litParent, resultType);
3439 /*------------------------------------------------------------------*/
3440 /*----------------------------*/
3442 /*----------------------------*/
3444 /* can be only integral type */
3445 if (!IS_INTEGRAL (LTYPE (tree)))
3447 werror (E_UNARY_OP, tree->opval.op);
3448 goto errorTreeReturn;
3451 /* if left is a literal then do it */
3452 if (IS_LITERAL (LTYPE (tree)))
3454 tree->type = EX_VALUE;
3455 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3457 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3458 return addCast (tree, resultType, TRUE);
3461 if (resultType == RESULT_TYPE_BIT &&
3462 IS_UNSIGNED (tree->left->etype) &&
3463 getSize (tree->left->etype) < INTSIZE)
3465 /* promotion rules are responsible for this strange result:
3466 bit -> int -> ~int -> bit
3467 uchar -> int -> ~int -> bit
3469 werror(W_COMPLEMENT);
3471 /* optimize bit-result, even if we optimize a buggy source */
3472 tree->type = EX_VALUE;
3473 tree->opval.val = constVal ("1");
3476 tree->left = addCast (tree->left, resultType, TRUE);
3478 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3481 /*------------------------------------------------------------------*/
3482 /*----------------------------*/
3484 /*----------------------------*/
3486 /* can be pointer */
3487 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3488 !IS_PTR (LTYPE (tree)) &&
3489 !IS_ARRAY (LTYPE (tree)))
3491 werror (E_UNARY_OP, tree->opval.op);
3492 goto errorTreeReturn;
3495 /* if left is another '!' */
3496 if (tree->left->opval.op == '!')
3498 /* remove double '!!X' by 'X ? 1 : 0' */
3499 tree->opval.op = '?';
3500 tree->left = tree->left->left;
3501 tree->right = newNode (':',
3502 newAst_VALUE (constVal ("1")),
3503 newAst_VALUE (constVal ("0")));
3504 tree->right->lineno = tree->lineno;
3505 tree->decorated = 0;
3506 return decorateType (tree, resultType);
3509 /* if left is a literal then do it */
3510 if (IS_LITERAL (LTYPE (tree)))
3512 tree->type = EX_VALUE;
3513 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3515 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3519 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3522 /*------------------------------------------------------------------*/
3523 /*----------------------------*/
3525 /*----------------------------*/
3529 TTYPE (tree) = LTYPE (tree);
3530 TETYPE (tree) = LETYPE (tree);
3535 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3539 TTYPE (tree) = TETYPE (tree) = newCharLink();
3543 TTYPE (tree) = TETYPE (tree) = newIntLink();
3548 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3550 werror (E_SHIFT_OP_INVALID);
3551 werror (W_CONTINUE, "left & right types are ");
3552 printTypeChain (LTYPE (tree), stderr);
3553 fprintf (stderr, ",");
3554 printTypeChain (RTYPE (tree), stderr);
3555 fprintf (stderr, "\n");
3556 goto errorTreeReturn;
3559 /* make smaller type only if it's a LEFT_OP */
3560 if (tree->opval.op == LEFT_OP)
3561 tree->left = addCast (tree->left, resultType, TRUE);
3563 /* if they are both literal then */
3564 /* rewrite the tree */
3565 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3567 tree->type = EX_VALUE;
3568 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3569 valFromType (RETYPE (tree)),
3570 (tree->opval.op == LEFT_OP ? 1 : 0));
3571 tree->right = tree->left = NULL;
3572 TETYPE (tree) = getSpec (TTYPE (tree) =
3573 tree->opval.val->type);
3577 /* see if this is a GETBYTE operation if yes
3580 ast *otree = optimizeGetByte (tree, resultType);
3583 return decorateType (otree, RESULT_TYPE_NONE);
3586 /* see if this is a GETWORD operation if yes
3589 ast *otree = optimizeGetWord (tree, resultType);
3592 return decorateType (otree, RESULT_TYPE_NONE);
3595 LRVAL (tree) = RRVAL (tree) = 1;
3596 if (tree->opval.op == LEFT_OP)
3598 TETYPE (tree) = getSpec (TTYPE (tree) =
3599 computeType (LTYPE (tree),
3606 /* no promotion necessary */
3607 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3608 if (IS_LITERAL (TTYPE (tree)))
3609 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3612 /* if only the right side is a literal & we are
3613 shifting more than size of the left operand then zero */
3614 if (IS_LITERAL (RTYPE (tree)) &&
3615 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3616 (getSize (TETYPE (tree)) * 8))
3618 if (tree->opval.op==LEFT_OP ||
3619 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3621 lineno=tree->lineno;
3622 werror (W_SHIFT_CHANGED,
3623 (tree->opval.op == LEFT_OP ? "left" : "right"));
3624 tree->type = EX_VALUE;
3625 tree->left = tree->right = NULL;
3626 tree->opval.val = constVal ("0");
3627 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3634 /*------------------------------------------------------------------*/
3635 /*----------------------------*/
3637 /*----------------------------*/
3638 case CAST: /* change the type */
3639 /* cannot cast to an aggregate type */
3640 if (IS_AGGREGATE (LTYPE (tree)))
3642 werror (E_CAST_ILLEGAL);
3643 goto errorTreeReturn;
3646 /* make sure the type is complete and sane */
3647 changePointer(LTYPE(tree));
3648 checkTypeSanity(LETYPE(tree), "(cast)");
3650 /* if 'from' and 'to' are the same remove the superflous cast, */
3651 /* this helps other optimizations */
3652 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3657 /* If code memory is read only, then pointers to code memory */
3658 /* implicitly point to constants -- make this explicit */
3660 sym_link *t = LTYPE(tree);
3661 while (t && t->next)
3663 if (IS_CODEPTR(t) && port->mem.code_ro)
3665 if (IS_SPEC(t->next))
3666 SPEC_CONST (t->next) = 1;
3668 DCL_PTR_CONST (t->next) = 1;
3675 /* if the right is a literal replace the tree */
3676 if (IS_LITERAL (RETYPE (tree))) {
3677 if (!IS_PTR (LTYPE (tree))) {
3678 tree->type = EX_VALUE;
3680 valCastLiteral (LTYPE (tree),
3681 floatFromVal (valFromType (RETYPE (tree))));
3684 TTYPE (tree) = tree->opval.val->type;
3685 tree->values.literalFromCast = 1;
3686 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3687 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3688 sym_link *rest = LTYPE(tree)->next;
3689 werror(W_LITERAL_GENERIC);
3690 TTYPE(tree) = newLink(DECLARATOR);
3691 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3692 TTYPE(tree)->next = rest;
3693 tree->left->opval.lnk = TTYPE(tree);
3696 TTYPE (tree) = LTYPE (tree);
3700 TTYPE (tree) = LTYPE (tree);
3704 #if 0 // this is already checked, now this could be explicit
3705 /* if pointer to struct then check names */
3706 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3707 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3708 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3710 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3711 SPEC_STRUCT(LETYPE(tree))->tag);
3714 if (IS_ADDRESS_OF_OP(tree->right)
3715 && IS_AST_SYM_VALUE (tree->right->left)
3716 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3718 symbol * sym = AST_SYMBOL (tree->right->left);
3719 unsigned int gptype = 0;
3720 unsigned int addr = SPEC_ADDR (sym->etype);
3722 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3724 switch (SPEC_SCLS (sym->etype))
3727 gptype = GPTYPE_CODE;
3730 gptype = GPTYPE_FAR;
3734 gptype = GPTYPE_NEAR;
3737 gptype = GPTYPE_XSTACK;
3742 addr |= gptype << (8*(GPTRSIZE - 1));
3745 tree->type = EX_VALUE;
3747 valCastLiteral (LTYPE (tree), addr);
3748 TTYPE (tree) = tree->opval.val->type;
3749 TETYPE (tree) = getSpec (TTYPE (tree));
3752 tree->values.literalFromCast = 1;
3756 /* handle offsetof macro: */
3757 /* #define offsetof(TYPE, MEMBER) \ */
3758 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3759 if (IS_ADDRESS_OF_OP(tree->right)
3760 && IS_AST_OP (tree->right->left)
3761 && tree->right->left->opval.op == PTR_OP
3762 && IS_AST_OP (tree->right->left->left)
3763 && tree->right->left->left->opval.op == CAST
3764 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3766 symbol *element = getStructElement (
3767 SPEC_STRUCT (LETYPE(tree->right->left)),
3768 AST_SYMBOL(tree->right->left->right)
3772 tree->type = EX_VALUE;
3773 tree->opval.val = valCastLiteral (
3776 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3779 TTYPE (tree) = tree->opval.val->type;
3780 TETYPE (tree) = getSpec (TTYPE (tree));
3787 /* if the right is a literal replace the tree */
3788 if (IS_LITERAL (RETYPE (tree))) {
3790 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3791 /* rewrite (type *)litaddr
3793 and define type at litaddr temp
3794 (but only if type's storage class is not generic)
3796 ast *newTree = newNode ('&', NULL, NULL);
3799 TTYPE (newTree) = LTYPE (tree);
3800 TETYPE (newTree) = getSpec(LTYPE (tree));
3802 /* define a global symbol at the casted address*/
3803 sym = newSymbol(genSymName (0), 0);
3804 sym->type = LTYPE (tree)->next;
3806 sym->type = newLink (V_VOID);
3807 sym->etype = getSpec(sym->type);
3808 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3809 sym->lineDef = tree->lineno;
3812 SPEC_STAT (sym->etype) = 1;
3813 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3814 SPEC_ABSA(sym->etype) = 1;
3815 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3818 newTree->left = newAst_VALUE(symbolVal(sym));
3819 newTree->left->lineno = tree->lineno;
3820 LTYPE (newTree) = sym->type;
3821 LETYPE (newTree) = sym->etype;
3822 LLVAL (newTree) = 1;
3823 LRVAL (newTree) = 0;
3824 TLVAL (newTree) = 1;
3828 if (!IS_PTR (LTYPE (tree))) {
3829 tree->type = EX_VALUE;
3831 valCastLiteral (LTYPE (tree),
3832 floatFromVal (valFromType (RTYPE (tree))));
3833 TTYPE (tree) = tree->opval.val->type;
3836 tree->values.literalFromCast = 1;
3837 TETYPE (tree) = getSpec (TTYPE (tree));
3841 TTYPE (tree) = LTYPE (tree);
3845 TETYPE (tree) = getSpec (TTYPE (tree));
3849 /*------------------------------------------------------------------*/
3850 /*----------------------------*/
3851 /* logical &&, || */
3852 /*----------------------------*/
3855 /* each must be arithmetic type or be a pointer */
3856 if (!IS_PTR (LTYPE (tree)) &&
3857 !IS_ARRAY (LTYPE (tree)) &&
3858 !IS_INTEGRAL (LTYPE (tree)))
3860 werror (E_COMPARE_OP);
3861 goto errorTreeReturn;
3864 if (!IS_PTR (RTYPE (tree)) &&
3865 !IS_ARRAY (RTYPE (tree)) &&
3866 !IS_INTEGRAL (RTYPE (tree)))
3868 werror (E_COMPARE_OP);
3869 goto errorTreeReturn;
3871 /* if they are both literal then */
3872 /* rewrite the tree */
3873 if (IS_LITERAL (RTYPE (tree)) &&
3874 IS_LITERAL (LTYPE (tree)))
3876 tree->type = EX_VALUE;
3877 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3878 valFromType (RTYPE (tree)),
3880 tree->right = tree->left = NULL;
3881 TETYPE (tree) = getSpec (TTYPE (tree) =
3882 tree->opval.val->type);
3885 LRVAL (tree) = RRVAL (tree) = 1;
3886 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3889 /*------------------------------------------------------------------*/
3890 /*----------------------------*/
3891 /* comparison operators */
3892 /*----------------------------*/
3900 ast *lt = optimizeCompare (tree);
3906 /* if they are pointers they must be castable */
3907 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3909 if (tree->opval.op==EQ_OP &&
3910 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3911 // we cannot cast a gptr to a !gptr: switch the leaves
3912 struct ast *s=tree->left;
3913 tree->left=tree->right;
3916 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3918 werror (E_COMPARE_OP);
3919 fprintf (stderr, "comparing type ");
3920 printTypeChain (LTYPE (tree), stderr);
3921 fprintf (stderr, "to type ");
3922 printTypeChain (RTYPE (tree), stderr);
3923 fprintf (stderr, "\n");
3924 goto errorTreeReturn;
3927 /* else they should be promotable to one another */
3930 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3931 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3933 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3935 werror (E_COMPARE_OP);
3936 fprintf (stderr, "comparing type ");
3937 printTypeChain (LTYPE (tree), stderr);
3938 fprintf (stderr, "to type ");
3939 printTypeChain (RTYPE (tree), stderr);
3940 fprintf (stderr, "\n");
3941 goto errorTreeReturn;
3946 CCR_RESULT ccr_result = CCR_OK;
3948 /* if left is integral and right is literal
3949 then check constant range */
3950 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
3951 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
3952 tree->opval.op, FALSE);
3953 if (ccr_result == CCR_OK &&
3954 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
3955 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
3956 tree->opval.op, TRUE);
3959 case CCR_ALWAYS_TRUE:
3960 case CCR_ALWAYS_FALSE:
3961 if (!options.lessPedantic)
3962 werror (W_COMP_RANGE,
3963 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
3964 return decorateType (newAst_VALUE (constVal (
3965 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
3973 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3974 if (tree->opval.op == '>' &&
3975 SPEC_USIGN(LETYPE(tree)) &&
3976 IS_LITERAL(RTYPE(tree)) &&
3977 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3979 if (resultType == RESULT_TYPE_IFX)
3981 /* the parent is an ifx: */
3982 /* if (unsigned value) */
3986 /* (unsigned value) ? 1 : 0 */
3987 tree->opval.op = '?';
3988 tree->right = newNode (':',
3989 newAst_VALUE (constVal ("1")),
3990 tree->right); /* val 0 */
3991 tree->right->lineno = tree->lineno;
3992 tree->right->left->lineno = tree->lineno;
3993 tree->decorated = 0;
3994 return decorateType (tree, resultType);
3997 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
3998 if (IS_LITERAL(RTYPE(tree)) &&
3999 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4000 tree->opval.op == EQ_OP &&
4001 resultType == RESULT_TYPE_IFX)
4003 tree->opval.op = '!';
4005 tree->decorated = 0;
4006 return decorateType (tree, resultType);
4009 /* if they are both literal then */
4010 /* rewrite the tree */
4011 if (IS_LITERAL (RTYPE (tree)) &&
4012 IS_LITERAL (LTYPE (tree)))
4014 tree->type = EX_VALUE;
4015 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4016 valFromType (RETYPE (tree)),
4018 tree->right = tree->left = NULL;
4019 TETYPE (tree) = getSpec (TTYPE (tree) =
4020 tree->opval.val->type);
4024 /* if one is 'signed char ' and the other one is 'unsigned char' */
4025 /* it's necessary to promote to int */
4026 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4027 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4029 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4030 if it's possible to use a 'signed char' */
4032 /* is left a 'unsigned char'? */
4033 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4034 /* the value range of a 'unsigned char' is 0...255;
4035 if the actual value is < 128 it can be changed to signed */
4036 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
4038 /* now we've got 2 'signed char'! */
4039 SPEC_USIGN (RETYPE (tree)) = 0;
4041 /* same test for the left operand: */
4042 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4043 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4045 SPEC_USIGN (LETYPE (tree)) = 0;
4049 werror (W_CMP_SU_CHAR);
4050 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4051 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4055 LRVAL (tree) = RRVAL (tree) = 1;
4056 TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4058 /* condition transformations */
4060 unsigned transformedOp = 0;
4062 switch (tree->opval.op)
4064 case '<': /* transform (a < b) to !(a >= b) */
4066 transformedOp = GE_OP;
4068 case '>': /* transform (a > b) to !(a <= b) */
4070 transformedOp = LE_OP;
4072 case LE_OP: /* transform (a <= b) to !(a > b) */
4074 transformedOp = '>';
4076 case GE_OP: /* transform (a >= b) to !(a < b) */
4078 transformedOp = '<';
4080 case NE_OP: /* transform (a != b) to !(a == b) */
4082 transformedOp = EQ_OP;
4084 case EQ_OP: /* transform (a == b) to !(a != b) */
4086 transformedOp = NE_OP;
4093 tree->opval.op = transformedOp;
4094 tree->decorated = 0;
4095 tree = newNode ('!', tree, NULL);
4096 tree->lineno = tree->left->lineno;
4097 return decorateType (tree, resultType);
4103 /*------------------------------------------------------------------*/
4104 /*----------------------------*/
4106 /*----------------------------*/
4107 case SIZEOF: /* evaluate wihout code generation */
4108 /* change the type to a integer */
4110 int size = getSize (tree->right->ftype);
4111 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4112 if (!size && !IS_VOID(tree->right->ftype))
4113 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4115 tree->type = EX_VALUE;
4116 tree->opval.val = constVal (buffer);
4117 tree->right = tree->left = NULL;
4118 TETYPE (tree) = getSpec (TTYPE (tree) =
4119 tree->opval.val->type);
4122 /*------------------------------------------------------------------*/
4123 /*----------------------------*/
4125 /*----------------------------*/
4127 /* return typeof enum value */
4128 tree->type = EX_VALUE;
4131 if (IS_SPEC(tree->right->ftype)) {
4132 switch (SPEC_NOUN(tree->right->ftype)) {
4134 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4135 else typeofv = TYPEOF_INT;
4138 typeofv = TYPEOF_FLOAT;
4141 typeofv = TYPEOF_FIXED16X16;
4144 typeofv = TYPEOF_CHAR;
4147 typeofv = TYPEOF_VOID;
4150 typeofv = TYPEOF_STRUCT;
4153 typeofv = TYPEOF_BITFIELD;
4156 typeofv = TYPEOF_BIT;
4159 typeofv = TYPEOF_SBIT;
4165 switch (DCL_TYPE(tree->right->ftype)) {
4167 typeofv = TYPEOF_POINTER;
4170 typeofv = TYPEOF_FPOINTER;
4173 typeofv = TYPEOF_CPOINTER;
4176 typeofv = TYPEOF_GPOINTER;
4179 typeofv = TYPEOF_PPOINTER;
4182 typeofv = TYPEOF_IPOINTER;
4185 typeofv = TYPEOF_ARRAY;
4188 typeofv = TYPEOF_FUNCTION;
4194 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4195 tree->opval.val = constVal (buffer);
4196 tree->right = tree->left = NULL;
4197 TETYPE (tree) = getSpec (TTYPE (tree) =
4198 tree->opval.val->type);
4201 /*------------------------------------------------------------------*/
4202 /*----------------------------*/
4203 /* conditional operator '?' */
4204 /*----------------------------*/
4206 /* the type is value of the colon operator (on the right) */
4207 assert (IS_COLON_OP (tree->right));
4208 /* if already known then replace the tree : optimizer will do it
4209 but faster to do it here */
4210 if (IS_LITERAL (LTYPE (tree)))
4212 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4213 return decorateType (tree->right->left, resultTypeProp);
4215 return decorateType (tree->right->right, resultTypeProp);
4219 tree->right = decorateType (tree->right, resultTypeProp);
4220 TTYPE (tree) = RTYPE (tree);
4221 TETYPE (tree) = getSpec (TTYPE (tree));
4226 /* if they don't match we have a problem */
4227 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4228 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4230 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4231 goto errorTreeReturn;
4234 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4235 resultType, tree->opval.op);
4236 TETYPE (tree) = getSpec (TTYPE (tree));
4240 #if 0 // assignment operators are converted by the parser
4241 /*------------------------------------------------------------------*/
4242 /*----------------------------*/
4243 /* assignment operators */
4244 /*----------------------------*/
4247 /* for these it must be both must be integral */
4248 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4249 !IS_ARITHMETIC (RTYPE (tree)))
4251 werror (E_OPS_INTEGRAL);
4252 goto errorTreeReturn;
4255 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4257 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4258 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4262 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4263 goto errorTreeReturn;
4274 /* for these it must be both must be integral */
4275 if (!IS_INTEGRAL (LTYPE (tree)) ||
4276 !IS_INTEGRAL (RTYPE (tree)))
4278 werror (E_OPS_INTEGRAL);
4279 goto errorTreeReturn;
4282 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4284 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4285 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4289 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4290 goto errorTreeReturn;
4296 /*------------------------------------------------------------------*/
4297 /*----------------------------*/
4299 /*----------------------------*/
4301 if (!(IS_PTR (LTYPE (tree)) ||
4302 IS_ARITHMETIC (LTYPE (tree))))
4304 werror (E_PLUS_INVALID, "-=");
4305 goto errorTreeReturn;
4308 if (!(IS_PTR (RTYPE (tree)) ||
4309 IS_ARITHMETIC (RTYPE (tree))))
4311 werror (E_PLUS_INVALID, "-=");
4312 goto errorTreeReturn;
4315 TETYPE (tree) = getSpec (TTYPE (tree) =
4316 computeType (LTYPE (tree),
4321 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4322 werror (E_CODE_WRITE, "-=");
4326 werror (E_LVALUE_REQUIRED, "-=");
4327 goto errorTreeReturn;
4333 /*------------------------------------------------------------------*/
4334 /*----------------------------*/
4336 /*----------------------------*/
4338 /* this is not a unary operation */
4339 /* if both pointers then problem */
4340 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4342 werror (E_PTR_PLUS_PTR);
4343 goto errorTreeReturn;
4346 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4348 werror (E_PLUS_INVALID, "+=");
4349 goto errorTreeReturn;
4352 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4354 werror (E_PLUS_INVALID, "+=");
4355 goto errorTreeReturn;
4358 TETYPE (tree) = getSpec (TTYPE (tree) =
4359 computeType (LTYPE (tree),
4364 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4365 werror (E_CODE_WRITE, "+=");
4369 werror (E_LVALUE_REQUIRED, "+=");
4370 goto errorTreeReturn;
4373 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4374 tree->opval.op = '=';
4379 /*------------------------------------------------------------------*/
4380 /*----------------------------*/
4381 /* straight assignemnt */
4382 /*----------------------------*/
4384 /* cannot be an aggregate */
4385 if (IS_AGGREGATE (LTYPE (tree)))
4387 werror (E_AGGR_ASSIGN);
4388 goto errorTreeReturn;
4391 /* they should either match or be castable */
4392 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4394 werror (E_TYPE_MISMATCH, "assignment", " ");
4395 printFromToType(RTYPE(tree),LTYPE(tree));
4398 /* if the left side of the tree is of type void
4399 then report error */
4400 if (IS_VOID (LTYPE (tree)))
4402 werror (E_CAST_ZERO);
4403 printFromToType(RTYPE(tree), LTYPE(tree));
4406 TETYPE (tree) = getSpec (TTYPE (tree) =
4410 if (!tree->initMode ) {
4411 if (IS_CONSTANT(LTYPE(tree)))
4412 werror (E_CODE_WRITE, "=");
4416 werror (E_LVALUE_REQUIRED, "=");
4417 goto errorTreeReturn;
4422 /*------------------------------------------------------------------*/
4423 /*----------------------------*/
4424 /* comma operator */
4425 /*----------------------------*/
4427 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4430 /*------------------------------------------------------------------*/
4431 /*----------------------------*/
4433 /*----------------------------*/
4436 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4437 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4439 if (tree->left->opval.op == '*' && !tree->left->right)
4440 tree->left = tree->left->left;
4443 /* require a function or pointer to function */
4444 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4446 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4447 goto errorTreeReturn;
4450 /* if there are parms, make sure that
4451 parms are decorate / process / reverse only once */
4453 !tree->right->decorated)
4458 if (IS_FUNCPTR (LTYPE (tree)))
4460 functype = LTYPE (tree)->next;
4461 processFuncPtrArgs (functype);
4464 functype = LTYPE (tree);
4466 if (processParms (tree->left, FUNC_ARGS(functype),
4467 &tree->right, &parmNumber, TRUE))
4469 goto errorTreeReturn;
4472 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4473 !IFFUNC_ISBUILTIN(functype))
4475 reverseParms (tree->right);
4478 TTYPE (tree) = functype->next;
4479 TETYPE (tree) = getSpec (TTYPE (tree));
4483 /*------------------------------------------------------------------*/
4484 /*----------------------------*/
4485 /* return statement */
4486 /*----------------------------*/
4491 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4493 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4494 printFromToType (RTYPE(tree), currFunc->type->next);
4495 goto errorTreeReturn;
4498 if (IS_VOID (currFunc->type->next)
4500 !IS_VOID (RTYPE (tree)))
4502 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4503 goto errorTreeReturn;
4506 /* if there is going to be a casting required then add it */
4507 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4510 decorateType (newNode (CAST,
4511 newAst_LINK (copyLinkChain (currFunc->type->next)),
4521 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4523 werror (W_VOID_FUNC, currFunc->name);
4524 goto errorTreeReturn;
4527 TTYPE (tree) = TETYPE (tree) = NULL;
4530 /*------------------------------------------------------------------*/
4531 /*----------------------------*/
4532 /* switch statement */
4533 /*----------------------------*/
4535 /* the switch value must be an integer */
4536 if (!IS_INTEGRAL (LTYPE (tree)))
4538 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4539 goto errorTreeReturn;
4542 TTYPE (tree) = TETYPE (tree) = NULL;
4545 /*------------------------------------------------------------------*/
4546 /*----------------------------*/
4548 /*----------------------------*/
4550 tree->left = backPatchLabels (tree->left,
4553 TTYPE (tree) = TETYPE (tree) = NULL;
4556 /*------------------------------------------------------------------*/
4557 /*----------------------------*/
4559 /*----------------------------*/
4562 AST_FOR (tree, initExpr) = decorateType (
4563 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4564 AST_FOR (tree, condExpr) = decorateType (
4565 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4566 AST_FOR (tree, loopExpr) = decorateType (
4567 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4569 /* if the for loop is reversible then
4570 reverse it otherwise do what we normally
4576 if (isLoopReversible (tree, &sym, &init, &end))
4577 return reverseLoop (tree, sym, init, end);
4579 return decorateType (createFor (AST_FOR (tree, trueLabel),
4580 AST_FOR (tree, continueLabel),
4581 AST_FOR (tree, falseLabel),
4582 AST_FOR (tree, condLabel),
4583 AST_FOR (tree, initExpr),
4584 AST_FOR (tree, condExpr),
4585 AST_FOR (tree, loopExpr),
4586 tree->left), RESULT_TYPE_NONE);
4589 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4590 "node PARAM shouldn't be processed here");
4591 /* but in processParams() */
4594 TTYPE (tree) = TETYPE (tree) = NULL;
4598 /* some error found this tree will be killed */
4600 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4601 tree->opval.op = NULLOP;
4607 /*-----------------------------------------------------------------*/
4608 /* sizeofOp - processes size of operation */
4609 /*-----------------------------------------------------------------*/
4611 sizeofOp (sym_link * type)
4616 /* make sure the type is complete and sane */
4617 checkTypeSanity(type, "(sizeof)");
4619 /* get the size and convert it to character */
4620 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4621 if (!size && !IS_VOID(type))
4622 werror (E_SIZEOF_INCOMPLETE_TYPE);
4624 /* now convert into value */
4625 return constVal (buff);
4629 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4630 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4631 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4632 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4633 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4634 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4635 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4637 /*-----------------------------------------------------------------*/
4638 /* backPatchLabels - change and or not operators to flow control */
4639 /*-----------------------------------------------------------------*/
4641 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4647 /* while-loops insert a label between the IFX and the condition,
4648 therefore look behind the label too */
4649 if (tree->opval.op == LABEL &&
4650 IS_ANDORNOT (tree->right))
4652 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4656 if (!(IS_ANDORNOT (tree)))
4659 /* if this an and */
4662 static int localLbl = 0;
4665 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4666 localLabel = newSymbol (buffer, NestLevel);
4668 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4670 /* if left is already a IFX then just change the if true label in that */
4671 if (!IS_IFX (tree->left))
4672 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4674 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4675 /* right is a IFX then just join */
4676 if (IS_IFX (tree->right))
4677 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4679 tree->right = createLabel (localLabel, tree->right);
4680 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4682 return newNode (NULLOP, tree->left, tree->right);
4685 /* if this is an or operation */
4688 static int localLbl = 0;
4691 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4692 localLabel = newSymbol (buffer, NestLevel);
4694 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4696 /* if left is already a IFX then just change the if true label in that */
4697 if (!IS_IFX (tree->left))
4698 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4700 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4701 /* right is a IFX then just join */
4702 if (IS_IFX (tree->right))
4703 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4705 tree->right = createLabel (localLabel, tree->right);
4706 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4708 return newNode (NULLOP, tree->left, tree->right);
4714 /* call with exchanged labels */
4715 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4717 /* if left isn't already a IFX */
4718 if (!IS_IFX (tree->left))
4720 tree->left = newNode (IFX, tree->left, NULL);
4721 tree->left->trueLabel = falseLabel;
4722 tree->left->falseLabel = trueLabel;
4729 tree->trueLabel = trueLabel;
4730 tree->falseLabel = falseLabel;
4737 /*-----------------------------------------------------------------*/
4738 /* createBlock - create expression tree for block */
4739 /*-----------------------------------------------------------------*/
4741 createBlock (symbol * decl, ast * body)
4745 /* if the block has nothing */
4749 ex = newNode (BLOCK, NULL, body);
4750 ex->values.sym = decl;
4757 /*-----------------------------------------------------------------*/
4758 /* createLabel - creates the expression tree for labels */
4759 /*-----------------------------------------------------------------*/
4761 createLabel (symbol * label, ast * stmnt)
4764 char name[SDCC_NAME_MAX + 1];
4767 /* must create fresh symbol if the symbol name */
4768 /* exists in the symbol table, since there can */
4769 /* be a variable with the same name as the labl */
4770 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4771 (csym->level == label->level))
4772 label = newSymbol (label->name, label->level);
4774 /* change the name before putting it in add _ */
4775 SNPRINTF(name, sizeof(name), "%s", label->name);
4777 /* put the label in the LabelSymbol table */
4778 /* but first check if a label of the same */
4780 if ((csym = findSym (LabelTab, NULL, name)))
4781 werror (E_DUPLICATE_LABEL, label->name);
4783 addSym (LabelTab, label, name, label->level, 0, 0);
4787 label->key = labelKey++;
4788 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4794 /*-----------------------------------------------------------------*/
4795 /* createCase - generates the parsetree for a case statement */
4796 /*-----------------------------------------------------------------*/
4798 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4800 char caseLbl[SDCC_NAME_MAX + 1];
4804 /* if the switch statement does not exist */
4805 /* then case is out of context */
4808 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4812 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4813 /* if not a constant then error */
4814 if (!IS_LITERAL (caseVal->ftype))
4816 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4820 /* if not a integer than error */
4821 if (!IS_INTEGRAL (caseVal->ftype))
4823 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4827 /* find the end of the switch values chain */
4828 if (!(val = swStat->values.switchVals.swVals))
4829 swStat->values.switchVals.swVals = caseVal->opval.val;
4832 /* also order the cases according to value */
4834 int cVal = (int) floatFromVal (caseVal->opval.val);
4835 while (val && (int) floatFromVal (val) < cVal)
4841 /* if we reached the end then */
4844 pval->next = caseVal->opval.val;
4846 else if ((int) floatFromVal (val) == cVal)
4848 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4854 /* we found a value greater than */
4855 /* the current value we must add this */
4856 /* before the value */
4857 caseVal->opval.val->next = val;
4859 /* if this was the first in chain */
4860 if (swStat->values.switchVals.swVals == val)
4861 swStat->values.switchVals.swVals =
4864 pval->next = caseVal->opval.val;
4869 /* create the case label */
4870 SNPRINTF(caseLbl, sizeof(caseLbl),
4872 swStat->values.switchVals.swNum,
4873 (int) floatFromVal (caseVal->opval.val));
4875 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4880 /*-----------------------------------------------------------------*/
4881 /* createDefault - creates the parse tree for the default statement */
4882 /*-----------------------------------------------------------------*/
4884 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4886 char defLbl[SDCC_NAME_MAX + 1];
4888 /* if the switch statement does not exist */
4889 /* then case is out of context */
4892 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4896 if (swStat->values.switchVals.swDefault)
4898 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4903 /* turn on the default flag */
4904 swStat->values.switchVals.swDefault = 1;
4906 /* create the label */
4907 SNPRINTF (defLbl, sizeof(defLbl),
4908 "_default_%d", swStat->values.switchVals.swNum);
4909 return createLabel (newSymbol (defLbl, 0), stmnt);
4912 /*-----------------------------------------------------------------*/
4913 /* createIf - creates the parsetree for the if statement */
4914 /*-----------------------------------------------------------------*/
4916 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4918 static int Lblnum = 0;
4920 symbol *ifTrue, *ifFalse, *ifEnd;
4922 /* if neither exists */
4923 if (!elseBody && !ifBody) {
4924 // if there are no side effects (i++, j() etc)
4925 if (!hasSEFcalls(condAst)) {
4930 /* create the labels */
4931 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4932 ifFalse = newSymbol (buffer, NestLevel);
4933 /* if no else body then end == false */
4938 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4939 ifEnd = newSymbol (buffer, NestLevel);
4942 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4943 ifTrue = newSymbol (buffer, NestLevel);
4947 /* attach the ifTrue label to the top of it body */
4948 ifBody = createLabel (ifTrue, ifBody);
4949 /* attach a goto end to the ifBody if else is present */
4952 ifBody = newNode (NULLOP, ifBody,
4954 newAst_VALUE (symbolVal (ifEnd)),
4956 /* put the elseLabel on the else body */
4957 elseBody = createLabel (ifFalse, elseBody);
4958 /* out the end at the end of the body */
4959 elseBody = newNode (NULLOP,
4961 createLabel (ifEnd, NULL));
4965 ifBody = newNode (NULLOP, ifBody,
4966 createLabel (ifFalse, NULL));
4968 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4969 if (IS_IFX (condAst))
4972 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4974 return newNode (NULLOP, ifTree,
4975 newNode (NULLOP, ifBody, elseBody));
4979 /*-----------------------------------------------------------------*/
4980 /* createDo - creates parse tree for do */
4983 /* _docontinue_n: */
4984 /* condition_expression +-> trueLabel -> _dobody_n */
4986 /* +-> falseLabel-> _dobreak_n */
4988 /*-----------------------------------------------------------------*/
4990 createDo (symbol * trueLabel, symbol * continueLabel,
4991 symbol * falseLabel, ast * condAst, ast * doBody)
4996 /* if the body does not exist then it is simple */
4999 condAst = backPatchLabels (condAst, continueLabel, NULL);
5000 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5001 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5002 doTree->trueLabel = continueLabel;
5003 doTree->falseLabel = NULL;
5007 /* otherwise we have a body */
5008 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5010 /* attach the body label to the top */
5011 doBody = createLabel (trueLabel, doBody);
5012 /* attach the continue label to end of body */
5013 doBody = newNode (NULLOP, doBody,
5014 createLabel (continueLabel, NULL));
5016 /* now put the break label at the end */
5017 if (IS_IFX (condAst))
5020 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5022 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5024 /* putting it together */
5025 return newNode (NULLOP, doBody, doTree);
5028 /*-----------------------------------------------------------------*/
5029 /* createFor - creates parse tree for 'for' statement */
5032 /* condExpr +-> trueLabel -> _forbody_n */
5034 /* +-> falseLabel-> _forbreak_n */
5037 /* _forcontinue_n: */
5039 /* goto _forcond_n ; */
5041 /*-----------------------------------------------------------------*/
5043 createFor (symbol * trueLabel, symbol * continueLabel,
5044 symbol * falseLabel, symbol * condLabel,
5045 ast * initExpr, ast * condExpr, ast * loopExpr,
5050 /* if loopexpression not present then we can generate it */
5051 /* the same way as a while */
5053 return newNode (NULLOP, initExpr,
5054 createWhile (trueLabel, continueLabel,
5055 falseLabel, condExpr, forBody));
5056 /* vanilla for statement */
5057 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5059 if (condExpr && !IS_IFX (condExpr))
5060 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5063 /* attach condition label to condition */
5064 condExpr = createLabel (condLabel, condExpr);
5066 /* attach body label to body */
5067 forBody = createLabel (trueLabel, forBody);
5069 /* attach continue to forLoop expression & attach */
5070 /* goto the forcond @ and of loopExpression */
5071 loopExpr = createLabel (continueLabel,
5075 newAst_VALUE (symbolVal (condLabel)),
5077 /* now start putting them together */
5078 forTree = newNode (NULLOP, initExpr, condExpr);
5079 forTree = newNode (NULLOP, forTree, forBody);
5080 forTree = newNode (NULLOP, forTree, loopExpr);
5081 /* finally add the break label */
5082 forTree = newNode (NULLOP, forTree,
5083 createLabel (falseLabel, NULL));
5087 /*-----------------------------------------------------------------*/
5088 /* createWhile - creates parse tree for while statement */
5089 /* the while statement will be created as follows */
5091 /* _while_continue_n: */
5092 /* condition_expression +-> trueLabel -> _while_boby_n */
5094 /* +-> falseLabel -> _while_break_n */
5095 /* _while_body_n: */
5097 /* goto _while_continue_n */
5098 /* _while_break_n: */
5099 /*-----------------------------------------------------------------*/
5101 createWhile (symbol * trueLabel, symbol * continueLabel,
5102 symbol * falseLabel, ast * condExpr, ast * whileBody)
5106 /* put the continue label */
5107 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5108 condExpr = createLabel (continueLabel, condExpr);
5109 condExpr->lineno = 0;
5111 /* put the body label in front of the body */
5112 whileBody = createLabel (trueLabel, whileBody);
5113 whileBody->lineno = 0;
5114 /* put a jump to continue at the end of the body */
5115 /* and put break label at the end of the body */
5116 whileBody = newNode (NULLOP,
5119 newAst_VALUE (symbolVal (continueLabel)),
5120 createLabel (falseLabel, NULL)));
5122 /* put it all together */
5123 if (IS_IFX (condExpr))
5124 whileTree = condExpr;
5127 whileTree = newNode (IFX, condExpr, NULL);
5128 /* put the true & false labels in place */
5129 whileTree->trueLabel = trueLabel;
5130 whileTree->falseLabel = falseLabel;
5133 return newNode (NULLOP, whileTree, whileBody);
5136 /*-----------------------------------------------------------------*/
5137 /* isShiftRightLitVal _BitAndLitVal - helper function */
5138 /*-----------------------------------------------------------------*/
5140 isShiftRightLitVal_BitAndLitVal (ast * tree)
5142 /* if this is not a bit and */
5143 if (!IS_BITAND (tree))
5146 /* will look for tree of the form
5147 ( expr >> litval2) & litval1 */
5148 if (!IS_AST_LIT_VALUE (tree->right))
5151 if (!IS_RIGHT_OP (tree->left))
5154 if (!IS_AST_LIT_VALUE (tree->left->right))
5157 return tree->left->left;
5160 /*-----------------------------------------------------------------*/
5161 /* isBitAndPowOf2 - helper function */
5162 /*-----------------------------------------------------------------*/
5164 isBitAndPow2 (ast * tree)
5166 /* if this is not a bit and */
5167 if (!IS_BITAND (tree))
5170 /* will look for tree of the form
5171 ( expr & (1 << litval) */
5172 if (!IS_AST_LIT_VALUE (tree->right))
5175 return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5178 /*-----------------------------------------------------------------*/
5179 /* optimizeGetHbit - get highest order bit of the expression */
5180 /*-----------------------------------------------------------------*/
5182 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5187 expr = isShiftRightLitVal_BitAndLitVal(tree);
5190 if ((AST_LIT_VALUE (tree->right) != 1) ||
5191 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5192 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5195 if (!expr && (resultType == RESULT_TYPE_BIT))
5198 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5204 /* make sure the port supports GETHBIT */
5205 if (port->hasExtBitOp
5206 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5209 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5212 /*-----------------------------------------------------------------*/
5213 /* optimizeGetAbit - get a single bit of the expression */
5214 /*-----------------------------------------------------------------*/
5216 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5221 expr = isShiftRightLitVal_BitAndLitVal(tree);
5224 if (AST_LIT_VALUE (tree->right) != 1)
5226 count = tree->left->right;
5228 if (!expr && (resultType == RESULT_TYPE_BIT))
5230 int p2 = isBitAndPow2 (tree);
5234 count = newAst_VALUE (valueFromLit (p2));
5240 /* make sure the port supports GETABIT */
5241 if (port->hasExtBitOp
5242 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5245 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5249 /*-----------------------------------------------------------------*/
5250 /* optimizeGetByte - get a byte of the expression */
5251 /*-----------------------------------------------------------------*/
5253 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5259 expr = isShiftRightLitVal_BitAndLitVal(tree);
5262 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5263 count = tree->left->right;
5264 if (AST_LIT_VALUE (tree->right) != 0xFF)
5267 if (!expr && resultType == RESULT_TYPE_CHAR)
5269 /* if this is a right shift over a multiple of 8 */
5270 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5272 i = (unsigned int) AST_LIT_VALUE (tree->right);
5273 count = tree->right;
5277 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5280 /* make sure the port supports GETBYTE */
5281 if (port->hasExtBitOp
5282 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5285 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5288 /*-----------------------------------------------------------------*/
5289 /* optimizeGetWord - get two bytes of the expression */
5290 /*-----------------------------------------------------------------*/
5292 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5298 expr = isShiftRightLitVal_BitAndLitVal(tree);
5301 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5302 count = tree->left->right;
5303 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5306 if (!expr && resultType == RESULT_TYPE_INT)
5308 /* if this is a right shift over a multiple of 8 */
5309 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5311 i = (unsigned int) AST_LIT_VALUE (tree->right);
5312 count = tree->right;
5316 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5319 /* make sure the port supports GETWORD */
5320 if (port->hasExtBitOp
5321 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5324 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5327 /*-----------------------------------------------------------------*/
5328 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5329 /*-----------------------------------------------------------------*/
5331 optimizeRRCRLC (ast * root)
5333 /* will look for trees of the form
5334 (?expr << 1) | (?expr >> 7) or
5335 (?expr >> 7) | (?expr << 1) will make that
5336 into a RLC : operation ..
5338 (?expr >> 1) | (?expr << 7) or
5339 (?expr << 7) | (?expr >> 1) will make that
5340 into a RRC operation
5341 note : by 7 I mean (number of bits required to hold the
5343 /* if the root operation is not a | operation then not */
5344 if (!IS_BITOR (root))
5347 /* I have to think of a better way to match patterns this sucks */
5348 /* that aside let's start looking for the first case : I use a
5349 negative check a lot to improve the efficiency */
5350 /* (?expr << 1) | (?expr >> 7) */
5351 if (IS_LEFT_OP (root->left) &&
5352 IS_RIGHT_OP (root->right))
5355 if (!SPEC_USIGN (TETYPE (root->left->left)))
5358 if (!IS_AST_LIT_VALUE (root->left->right) ||
5359 !IS_AST_LIT_VALUE (root->right->right))
5362 /* make sure it is the same expression */
5363 if (!isAstEqual (root->left->left,
5367 if (AST_LIT_VALUE (root->left->right) != 1)
5370 if (AST_LIT_VALUE (root->right->right) !=
5371 (getSize (TTYPE (root->left->left)) * 8 - 1))
5374 /* make sure the port supports RLC */
5375 if (port->hasExtBitOp
5376 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5379 /* whew got the first case : create the AST */
5380 return newNode (RLC, root->left->left, NULL);
5384 /* check for second case */
5385 /* (?expr >> 7) | (?expr << 1) */
5386 if (IS_LEFT_OP (root->right) &&
5387 IS_RIGHT_OP (root->left))
5390 if (!SPEC_USIGN (TETYPE (root->left->left)))
5393 if (!IS_AST_LIT_VALUE (root->left->right) ||
5394 !IS_AST_LIT_VALUE (root->right->right))
5397 /* make sure it is the same symbol */
5398 if (!isAstEqual (root->left->left,
5402 if (AST_LIT_VALUE (root->right->right) != 1)
5405 if (AST_LIT_VALUE (root->left->right) !=
5406 (getSize (TTYPE (root->left->left)) * 8 - 1))
5409 /* make sure the port supports RLC */
5410 if (port->hasExtBitOp
5411 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5414 /* whew got the first case : create the AST */
5415 return newNode (RLC, root->left->left, NULL);
5420 /* third case for RRC */
5421 /* (?symbol >> 1) | (?symbol << 7) */
5422 if (IS_LEFT_OP (root->right) &&
5423 IS_RIGHT_OP (root->left))
5426 if (!SPEC_USIGN (TETYPE (root->left->left)))
5429 if (!IS_AST_LIT_VALUE (root->left->right) ||
5430 !IS_AST_LIT_VALUE (root->right->right))
5433 /* make sure it is the same symbol */
5434 if (!isAstEqual (root->left->left,
5438 if (AST_LIT_VALUE (root->left->right) != 1)
5441 if (AST_LIT_VALUE (root->right->right) !=
5442 (getSize (TTYPE (root->left->left)) * 8 - 1))
5445 /* make sure the port supports RRC */
5446 if (port->hasExtBitOp
5447 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5450 /* whew got the first case : create the AST */
5451 return newNode (RRC, root->left->left, NULL);
5455 /* fourth and last case for now */
5456 /* (?symbol << 7) | (?symbol >> 1) */
5457 if (IS_RIGHT_OP (root->right) &&
5458 IS_LEFT_OP (root->left))
5461 if (!SPEC_USIGN (TETYPE (root->left->left)))
5464 if (!IS_AST_LIT_VALUE (root->left->right) ||
5465 !IS_AST_LIT_VALUE (root->right->right))
5468 /* make sure it is the same symbol */
5469 if (!isAstEqual (root->left->left,
5473 if (AST_LIT_VALUE (root->right->right) != 1)
5476 if (AST_LIT_VALUE (root->left->right) !=
5477 (getSize (TTYPE (root->left->left)) * 8 - 1))
5480 /* make sure the port supports RRC */
5481 if (port->hasExtBitOp
5482 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5485 /* whew got the first case : create the AST */
5486 return newNode (RRC, root->left->left, NULL);
5490 /* not found return root */
5494 /*-----------------------------------------------------------------*/
5495 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5496 /*-----------------------------------------------------------------*/
5498 optimizeSWAP (ast * root)
5500 /* will look for trees of the form
5501 (?expr << 4) | (?expr >> 4) or
5502 (?expr >> 4) | (?expr << 4) will make that
5503 into a SWAP : operation ..
5504 note : by 4 I mean (number of bits required to hold the
5506 /* if the root operation is not a | operation then not */
5507 if (!IS_BITOR (root))
5510 /* (?expr << 4) | (?expr >> 4) */
5511 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5512 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5515 if (!SPEC_USIGN (TETYPE (root->left->left)))
5518 if (!IS_AST_LIT_VALUE (root->left->right) ||
5519 !IS_AST_LIT_VALUE (root->right->right))
5522 /* make sure it is the same expression */
5523 if (!isAstEqual (root->left->left,
5527 if (AST_LIT_VALUE (root->left->right) !=
5528 (getSize (TTYPE (root->left->left)) * 4))
5531 if (AST_LIT_VALUE (root->right->right) !=
5532 (getSize (TTYPE (root->left->left)) * 4))
5535 /* make sure the port supports SWAP */
5536 if (port->hasExtBitOp
5537 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5540 /* found it : create the AST */
5541 return newNode (SWAP, root->left->left, NULL);
5545 /* not found return root */
5549 /*-----------------------------------------------------------------*/
5550 /* optimizeCompare - optimizes compares for bit variables */
5551 /*-----------------------------------------------------------------*/
5553 optimizeCompare (ast * root)
5555 ast *optExpr = NULL;
5558 unsigned int litValue;
5560 /* if nothing then return nothing */
5564 /* if not a compare op then do leaves */
5565 if (!IS_COMPARE_OP (root))
5567 root->left = optimizeCompare (root->left);
5568 root->right = optimizeCompare (root->right);
5572 /* if left & right are the same then depending
5573 of the operation do */
5574 if (isAstEqual (root->left, root->right))
5576 switch (root->opval.op)
5581 optExpr = newAst_VALUE (constVal ("0"));
5586 optExpr = newAst_VALUE (constVal ("1"));
5590 return decorateType (optExpr, RESULT_TYPE_NONE);
5593 vleft = (root->left->type == EX_VALUE ?
5594 root->left->opval.val : NULL);
5596 vright = (root->right->type == EX_VALUE ?
5597 root->right->opval.val : NULL);
5599 /* if left is a BITVAR in BITSPACE */
5600 /* and right is a LITERAL then opt- */
5601 /* imize else do nothing */
5602 if (vleft && vright &&
5603 IS_BITVAR (vleft->etype) &&
5604 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5605 IS_LITERAL (vright->etype))
5608 /* if right side > 1 then comparison may never succeed */
5609 if ((litValue = (int) floatFromVal (vright)) > 1)
5611 werror (W_BAD_COMPARE);
5617 switch (root->opval.op)
5619 case '>': /* bit value greater than 1 cannot be */
5620 werror (W_BAD_COMPARE);
5624 case '<': /* bit value < 1 means 0 */
5626 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5629 case LE_OP: /* bit value <= 1 means no check */
5630 optExpr = newAst_VALUE (vright);
5633 case GE_OP: /* bit value >= 1 means only check for = */
5635 optExpr = newAst_VALUE (vleft);
5640 { /* literal is zero */
5641 switch (root->opval.op)
5643 case '<': /* bit value < 0 cannot be */
5644 werror (W_BAD_COMPARE);
5648 case '>': /* bit value > 0 means 1 */
5650 optExpr = newAst_VALUE (vleft);
5653 case LE_OP: /* bit value <= 0 means no check */
5654 case GE_OP: /* bit value >= 0 means no check */
5655 werror (W_BAD_COMPARE);
5659 case EQ_OP: /* bit == 0 means ! of bit */
5660 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5664 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5665 } /* end-of-if of BITVAR */
5670 /*-----------------------------------------------------------------*/
5671 /* addSymToBlock : adds the symbol to the first block we find */
5672 /*-----------------------------------------------------------------*/
5674 addSymToBlock (symbol * sym, ast * tree)
5676 /* reached end of tree or a leaf */
5677 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5681 if (IS_AST_OP (tree) &&
5682 tree->opval.op == BLOCK)
5685 symbol *lsym = copySymbol (sym);
5687 lsym->next = AST_VALUES (tree, sym);
5688 AST_VALUES (tree, sym) = lsym;
5692 addSymToBlock (sym, tree->left);
5693 addSymToBlock (sym, tree->right);
5696 /*-----------------------------------------------------------------*/
5697 /* processRegParms - do processing for register parameters */
5698 /*-----------------------------------------------------------------*/
5700 processRegParms (value * args, ast * body)
5704 if (IS_REGPARM (args->etype))
5705 addSymToBlock (args->sym, body);
5710 /*-----------------------------------------------------------------*/
5711 /* resetParmKey - resets the operandkeys for the symbols */
5712 /*-----------------------------------------------------------------*/
5713 DEFSETFUNC (resetParmKey)
5724 /*-----------------------------------------------------------------*/
5725 /* createFunction - This is the key node that calls the iCode for */
5726 /* generating the code for a function. Note code */
5727 /* is generated function by function, later when */
5728 /* add inter-procedural analysis this will change */
5729 /*-----------------------------------------------------------------*/
5731 createFunction (symbol * name, ast * body)
5737 iCode *piCode = NULL;
5739 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5740 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5742 /* if check function return 0 then some problem */
5743 if (checkFunction (name, NULL) == 0)
5746 /* create a dummy block if none exists */
5748 body = newNode (BLOCK, NULL, NULL);
5752 /* check if the function name already in the symbol table */
5753 if ((csym = findSym (SymbolTab, NULL, name->name)))
5756 /* special case for compiler defined functions
5757 we need to add the name to the publics list : this
5758 actually means we are now compiling the compiler
5762 addSet (&publics, name);
5767 addSymChain (&name);
5768 allocVariables (name);
5770 name->lastLine = mylineno;
5773 /* set the stack pointer */
5774 stackPtr = -port->stack.direction * port->stack.call_overhead;
5777 if (IFFUNC_ISISR (name->type))
5778 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5780 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5782 if (options.useXstack)
5783 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5785 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5788 fetype = getSpec (name->type); /* get the specifier for the function */
5789 /* if this is a reentrant function then */
5790 if (IFFUNC_ISREENT (name->type))
5793 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5795 /* do processing for parameters that are passed in registers */
5796 processRegParms (FUNC_ARGS(name->type), body);
5798 /* set the stack pointer */
5802 /* allocate & autoinit the block variables */
5803 processBlockVars (body, &stack, ALLOCATE);
5805 /* save the stack information */
5806 if (options.useXstack)
5807 name->xstack = SPEC_STAK (fetype) = stack;
5809 name->stack = SPEC_STAK (fetype) = stack;
5811 /* name needs to be mangled */
5812 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5814 body = resolveSymbols (body); /* resolve the symbols */
5815 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5817 ex = newAst_VALUE (symbolVal (name)); /* create name */
5818 ex = newNode (FUNCTION, ex, body);
5819 ex->values.args = FUNC_ARGS(name->type);
5821 if (options.dump_tree) PA(ex);
5824 werror (E_FUNC_NO_CODE, name->name);
5828 /* create the node & generate intermediate code */
5830 codeOutFile = code->oFile;
5831 piCode = iCodeFromAst (ex);
5835 werror (E_FUNC_NO_CODE, name->name);
5839 eBBlockFromiCode (piCode);
5841 /* if there are any statics then do them */
5844 GcurMemmap = statsg;
5845 codeOutFile = statsg->oFile;
5846 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5852 /* dealloc the block variables */
5853 processBlockVars (body, &stack, DEALLOCATE);
5854 outputDebugStackSymbols();
5855 /* deallocate paramaters */
5856 deallocParms (FUNC_ARGS(name->type));
5858 if (IFFUNC_ISREENT (name->type))
5861 /* we are done freeup memory & cleanup */
5863 if (port->reset_labelKey) labelKey = 1;
5865 FUNC_HASBODY(name->type) = 1;
5866 addSet (&operKeyReset, name);
5867 applyToSet (operKeyReset, resetParmKey);
5872 cleanUpLevel (LabelTab, 0);
5873 cleanUpBlock (StructTab, 1);
5874 cleanUpBlock (TypedefTab, 1);
5876 xstack->syms = NULL;
5877 istack->syms = NULL;
5882 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5883 /*-----------------------------------------------------------------*/
5884 /* ast_print : prints the ast (for debugging purposes) */
5885 /*-----------------------------------------------------------------*/
5887 void ast_print (ast * tree, FILE *outfile, int indent)
5892 /* can print only decorated trees */
5893 if (!tree->decorated) return;
5895 /* if any child is an error | this one is an error do nothing */
5896 if (tree->isError ||
5897 (tree->left && tree->left->isError) ||
5898 (tree->right && tree->right->isError)) {
5899 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5903 /* print the line */
5904 /* if not block & function */
5905 if (tree->type == EX_OP &&
5906 (tree->opval.op != FUNCTION &&
5907 tree->opval.op != BLOCK &&
5908 tree->opval.op != NULLOP)) {
5911 if (tree->opval.op == FUNCTION) {
5913 value *args=FUNC_ARGS(tree->left->opval.val->type);
5914 fprintf(outfile,"FUNCTION (%s=%p) type (",
5915 tree->left->opval.val->name, tree);
5916 printTypeChain (tree->left->opval.val->type->next,outfile);
5917 fprintf(outfile,") args (");
5920 fprintf (outfile, ", ");
5922 printTypeChain (args ? args->type : NULL, outfile);
5924 args= args ? args->next : NULL;
5926 fprintf(outfile,")\n");
5927 ast_print(tree->left,outfile,indent);
5928 ast_print(tree->right,outfile,indent);
5931 if (tree->opval.op == BLOCK) {
5932 symbol *decls = tree->values.sym;
5933 INDENT(indent,outfile);
5934 fprintf(outfile,"{\n");
5936 INDENT(indent+2,outfile);
5937 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5938 decls->name, decls);
5939 printTypeChain(decls->type,outfile);
5940 fprintf(outfile,")\n");
5942 decls = decls->next;
5944 ast_print(tree->right,outfile,indent+2);
5945 INDENT(indent,outfile);
5946 fprintf(outfile,"}\n");
5949 if (tree->opval.op == NULLOP) {
5950 ast_print(tree->left,outfile,indent);
5951 ast_print(tree->right,outfile,indent);
5954 INDENT(indent,outfile);
5956 /*------------------------------------------------------------------*/
5957 /*----------------------------*/
5958 /* leaf has been reached */
5959 /*----------------------------*/
5960 /* if this is of type value */
5961 /* just get the type */
5962 if (tree->type == EX_VALUE) {
5964 if (IS_LITERAL (tree->opval.val->etype)) {
5965 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5966 if (SPEC_USIGN (tree->opval.val->etype))
5967 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5969 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5970 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5971 floatFromVal(tree->opval.val));
5972 } else if (tree->opval.val->sym) {
5973 /* if the undefined flag is set then give error message */
5974 if (tree->opval.val->sym->undefined) {
5975 fprintf(outfile,"UNDEFINED SYMBOL ");
5977 fprintf(outfile,"SYMBOL ");
5979 fprintf(outfile,"(%s=%p)",
5980 tree->opval.val->sym->name,tree);
5983 fprintf(outfile," type (");
5984 printTypeChain(tree->ftype,outfile);
5985 fprintf(outfile,")\n");
5987 fprintf(outfile,"\n");
5992 /* if type link for the case of cast */
5993 if (tree->type == EX_LINK) {
5994 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5995 printTypeChain(tree->opval.lnk,outfile);
5996 fprintf(outfile,")\n");
6001 /* depending on type of operator do */
6003 switch (tree->opval.op) {
6004 /*------------------------------------------------------------------*/
6005 /*----------------------------*/
6007 /*----------------------------*/
6009 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6010 printTypeChain(tree->ftype,outfile);
6011 fprintf(outfile,")\n");
6012 ast_print(tree->left,outfile,indent+2);
6013 ast_print(tree->right,outfile,indent+2);
6016 /*------------------------------------------------------------------*/
6017 /*----------------------------*/
6019 /*----------------------------*/
6021 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6022 printTypeChain(tree->ftype,outfile);
6023 fprintf(outfile,")\n");
6024 ast_print(tree->left,outfile,indent+2);
6025 ast_print(tree->right,outfile,indent+2);
6028 /*------------------------------------------------------------------*/
6029 /*----------------------------*/
6030 /* struct/union pointer */
6031 /*----------------------------*/
6033 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6034 printTypeChain(tree->ftype,outfile);
6035 fprintf(outfile,")\n");
6036 ast_print(tree->left,outfile,indent+2);
6037 ast_print(tree->right,outfile,indent+2);
6040 /*------------------------------------------------------------------*/
6041 /*----------------------------*/
6042 /* ++/-- operation */
6043 /*----------------------------*/
6046 fprintf(outfile,"post-");
6048 fprintf(outfile,"pre-");
6049 fprintf(outfile,"INC_OP (%p) type (",tree);
6050 printTypeChain(tree->ftype,outfile);
6051 fprintf(outfile,")\n");
6052 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6053 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6058 fprintf(outfile,"post-");
6060 fprintf(outfile,"pre-");
6061 fprintf(outfile,"DEC_OP (%p) type (",tree);
6062 printTypeChain(tree->ftype,outfile);
6063 fprintf(outfile,")\n");
6064 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6065 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6068 /*------------------------------------------------------------------*/
6069 /*----------------------------*/
6071 /*----------------------------*/
6074 fprintf(outfile,"& (%p) type (",tree);
6075 printTypeChain(tree->ftype,outfile);
6076 fprintf(outfile,")\n");
6077 ast_print(tree->left,outfile,indent+2);
6078 ast_print(tree->right,outfile,indent+2);
6080 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6081 printTypeChain(tree->ftype,outfile);
6082 fprintf(outfile,")\n");
6083 ast_print(tree->left,outfile,indent+2);
6084 ast_print(tree->right,outfile,indent+2);
6087 /*----------------------------*/
6089 /*----------------------------*/
6091 fprintf(outfile,"OR (%p) type (",tree);
6092 printTypeChain(tree->ftype,outfile);
6093 fprintf(outfile,")\n");
6094 ast_print(tree->left,outfile,indent+2);
6095 ast_print(tree->right,outfile,indent+2);
6097 /*------------------------------------------------------------------*/
6098 /*----------------------------*/
6100 /*----------------------------*/
6102 fprintf(outfile,"XOR (%p) type (",tree);
6103 printTypeChain(tree->ftype,outfile);
6104 fprintf(outfile,")\n");
6105 ast_print(tree->left,outfile,indent+2);
6106 ast_print(tree->right,outfile,indent+2);
6109 /*------------------------------------------------------------------*/
6110 /*----------------------------*/
6112 /*----------------------------*/
6114 fprintf(outfile,"DIV (%p) type (",tree);
6115 printTypeChain(tree->ftype,outfile);
6116 fprintf(outfile,")\n");
6117 ast_print(tree->left,outfile,indent+2);
6118 ast_print(tree->right,outfile,indent+2);
6120 /*------------------------------------------------------------------*/
6121 /*----------------------------*/
6123 /*----------------------------*/
6125 fprintf(outfile,"MOD (%p) type (",tree);
6126 printTypeChain(tree->ftype,outfile);
6127 fprintf(outfile,")\n");
6128 ast_print(tree->left,outfile,indent+2);
6129 ast_print(tree->right,outfile,indent+2);
6132 /*------------------------------------------------------------------*/
6133 /*----------------------------*/
6134 /* address dereference */
6135 /*----------------------------*/
6136 case '*': /* can be unary : if right is null then unary operation */
6138 fprintf(outfile,"DEREF (%p) type (",tree);
6139 printTypeChain(tree->ftype,outfile);
6140 fprintf(outfile,")\n");
6141 ast_print(tree->left,outfile,indent+2);
6144 /*------------------------------------------------------------------*/
6145 /*----------------------------*/
6146 /* multiplication */
6147 /*----------------------------*/
6148 fprintf(outfile,"MULT (%p) type (",tree);
6149 printTypeChain(tree->ftype,outfile);
6150 fprintf(outfile,")\n");
6151 ast_print(tree->left,outfile,indent+2);
6152 ast_print(tree->right,outfile,indent+2);
6156 /*------------------------------------------------------------------*/
6157 /*----------------------------*/
6158 /* unary '+' operator */
6159 /*----------------------------*/
6163 fprintf(outfile,"UPLUS (%p) type (",tree);
6164 printTypeChain(tree->ftype,outfile);
6165 fprintf(outfile,")\n");
6166 ast_print(tree->left,outfile,indent+2);
6168 /*------------------------------------------------------------------*/
6169 /*----------------------------*/
6171 /*----------------------------*/
6172 fprintf(outfile,"ADD (%p) type (",tree);
6173 printTypeChain(tree->ftype,outfile);
6174 fprintf(outfile,")\n");
6175 ast_print(tree->left,outfile,indent+2);
6176 ast_print(tree->right,outfile,indent+2);
6179 /*------------------------------------------------------------------*/
6180 /*----------------------------*/
6182 /*----------------------------*/
6183 case '-': /* can be unary */
6185 fprintf(outfile,"UMINUS (%p) type (",tree);
6186 printTypeChain(tree->ftype,outfile);
6187 fprintf(outfile,")\n");
6188 ast_print(tree->left,outfile,indent+2);
6190 /*------------------------------------------------------------------*/
6191 /*----------------------------*/
6193 /*----------------------------*/
6194 fprintf(outfile,"SUB (%p) type (",tree);
6195 printTypeChain(tree->ftype,outfile);
6196 fprintf(outfile,")\n");
6197 ast_print(tree->left,outfile,indent+2);
6198 ast_print(tree->right,outfile,indent+2);
6201 /*------------------------------------------------------------------*/
6202 /*----------------------------*/
6204 /*----------------------------*/
6206 fprintf(outfile,"COMPL (%p) type (",tree);
6207 printTypeChain(tree->ftype,outfile);
6208 fprintf(outfile,")\n");
6209 ast_print(tree->left,outfile,indent+2);
6211 /*------------------------------------------------------------------*/
6212 /*----------------------------*/
6214 /*----------------------------*/
6216 fprintf(outfile,"NOT (%p) type (",tree);
6217 printTypeChain(tree->ftype,outfile);
6218 fprintf(outfile,")\n");
6219 ast_print(tree->left,outfile,indent+2);
6221 /*------------------------------------------------------------------*/
6222 /*----------------------------*/
6224 /*----------------------------*/
6226 fprintf(outfile,"RRC (%p) type (",tree);
6227 printTypeChain(tree->ftype,outfile);
6228 fprintf(outfile,")\n");
6229 ast_print(tree->left,outfile,indent+2);
6233 fprintf(outfile,"RLC (%p) type (",tree);
6234 printTypeChain(tree->ftype,outfile);
6235 fprintf(outfile,")\n");
6236 ast_print(tree->left,outfile,indent+2);
6239 fprintf(outfile,"SWAP (%p) type (",tree);
6240 printTypeChain(tree->ftype,outfile);
6241 fprintf(outfile,")\n");
6242 ast_print(tree->left,outfile,indent+2);
6245 fprintf(outfile,"GETHBIT (%p) type (",tree);
6246 printTypeChain(tree->ftype,outfile);
6247 fprintf(outfile,")\n");
6248 ast_print(tree->left,outfile,indent+2);
6251 fprintf(outfile,"GETABIT (%p) type (",tree);
6252 printTypeChain(tree->ftype,outfile);
6253 fprintf(outfile,")\n");
6254 ast_print(tree->left,outfile,indent+2);
6255 ast_print(tree->right,outfile,indent+2);
6258 fprintf(outfile,"GETBYTE (%p) type (",tree);
6259 printTypeChain(tree->ftype,outfile);
6260 fprintf(outfile,")\n");
6261 ast_print(tree->left,outfile,indent+2);
6262 ast_print(tree->right,outfile,indent+2);
6265 fprintf(outfile,"GETWORD (%p) type (",tree);
6266 printTypeChain(tree->ftype,outfile);
6267 fprintf(outfile,")\n");
6268 ast_print(tree->left,outfile,indent+2);
6269 ast_print(tree->right,outfile,indent+2);
6272 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6273 printTypeChain(tree->ftype,outfile);
6274 fprintf(outfile,")\n");
6275 ast_print(tree->left,outfile,indent+2);
6276 ast_print(tree->right,outfile,indent+2);
6279 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6280 printTypeChain(tree->ftype,outfile);
6281 fprintf(outfile,")\n");
6282 ast_print(tree->left,outfile,indent+2);
6283 ast_print(tree->right,outfile,indent+2);
6285 /*------------------------------------------------------------------*/
6286 /*----------------------------*/
6288 /*----------------------------*/
6289 case CAST: /* change the type */
6290 fprintf(outfile,"CAST (%p) from type (",tree);
6291 printTypeChain(tree->right->ftype,outfile);
6292 fprintf(outfile,") to type (");
6293 printTypeChain(tree->ftype,outfile);
6294 fprintf(outfile,")\n");
6295 ast_print(tree->right,outfile,indent+2);
6299 fprintf(outfile,"ANDAND (%p) type (",tree);
6300 printTypeChain(tree->ftype,outfile);
6301 fprintf(outfile,")\n");
6302 ast_print(tree->left,outfile,indent+2);
6303 ast_print(tree->right,outfile,indent+2);
6306 fprintf(outfile,"OROR (%p) type (",tree);
6307 printTypeChain(tree->ftype,outfile);
6308 fprintf(outfile,")\n");
6309 ast_print(tree->left,outfile,indent+2);
6310 ast_print(tree->right,outfile,indent+2);
6313 /*------------------------------------------------------------------*/
6314 /*----------------------------*/
6315 /* comparison operators */
6316 /*----------------------------*/
6318 fprintf(outfile,"GT(>) (%p) type (",tree);
6319 printTypeChain(tree->ftype,outfile);
6320 fprintf(outfile,")\n");
6321 ast_print(tree->left,outfile,indent+2);
6322 ast_print(tree->right,outfile,indent+2);
6325 fprintf(outfile,"LT(<) (%p) type (",tree);
6326 printTypeChain(tree->ftype,outfile);
6327 fprintf(outfile,")\n");
6328 ast_print(tree->left,outfile,indent+2);
6329 ast_print(tree->right,outfile,indent+2);
6332 fprintf(outfile,"LE(<=) (%p) type (",tree);
6333 printTypeChain(tree->ftype,outfile);
6334 fprintf(outfile,")\n");
6335 ast_print(tree->left,outfile,indent+2);
6336 ast_print(tree->right,outfile,indent+2);
6339 fprintf(outfile,"GE(>=) (%p) type (",tree);
6340 printTypeChain(tree->ftype,outfile);
6341 fprintf(outfile,")\n");
6342 ast_print(tree->left,outfile,indent+2);
6343 ast_print(tree->right,outfile,indent+2);
6346 fprintf(outfile,"EQ(==) (%p) type (",tree);
6347 printTypeChain(tree->ftype,outfile);
6348 fprintf(outfile,")\n");
6349 ast_print(tree->left,outfile,indent+2);
6350 ast_print(tree->right,outfile,indent+2);
6353 fprintf(outfile,"NE(!=) (%p) type (",tree);
6354 printTypeChain(tree->ftype,outfile);
6355 fprintf(outfile,")\n");
6356 ast_print(tree->left,outfile,indent+2);
6357 ast_print(tree->right,outfile,indent+2);
6358 /*------------------------------------------------------------------*/
6359 /*----------------------------*/
6361 /*----------------------------*/
6362 case SIZEOF: /* evaluate wihout code generation */
6363 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6366 /*------------------------------------------------------------------*/
6367 /*----------------------------*/
6368 /* conditional operator '?' */
6369 /*----------------------------*/
6371 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6372 printTypeChain(tree->ftype,outfile);
6373 fprintf(outfile,")\n");
6374 ast_print(tree->left,outfile,indent+2);
6375 ast_print(tree->right,outfile,indent+2);
6379 fprintf(outfile,"COLON(:) (%p) type (",tree);
6380 printTypeChain(tree->ftype,outfile);
6381 fprintf(outfile,")\n");
6382 ast_print(tree->left,outfile,indent+2);
6383 ast_print(tree->right,outfile,indent+2);
6386 /*------------------------------------------------------------------*/
6387 /*----------------------------*/
6388 /* assignment operators */
6389 /*----------------------------*/
6391 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6392 printTypeChain(tree->ftype,outfile);
6393 fprintf(outfile,")\n");
6394 ast_print(tree->left,outfile,indent+2);
6395 ast_print(tree->right,outfile,indent+2);
6398 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6399 printTypeChain(tree->ftype,outfile);
6400 fprintf(outfile,")\n");
6401 ast_print(tree->left,outfile,indent+2);
6402 ast_print(tree->right,outfile,indent+2);
6405 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6406 printTypeChain(tree->ftype,outfile);
6407 fprintf(outfile,")\n");
6408 ast_print(tree->left,outfile,indent+2);
6409 ast_print(tree->right,outfile,indent+2);
6412 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6413 printTypeChain(tree->ftype,outfile);
6414 fprintf(outfile,")\n");
6415 ast_print(tree->left,outfile,indent+2);
6416 ast_print(tree->right,outfile,indent+2);
6419 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6420 printTypeChain(tree->ftype,outfile);
6421 fprintf(outfile,")\n");
6422 ast_print(tree->left,outfile,indent+2);
6423 ast_print(tree->right,outfile,indent+2);
6426 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6427 printTypeChain(tree->ftype,outfile);
6428 fprintf(outfile,")\n");
6429 ast_print(tree->left,outfile,indent+2);
6430 ast_print(tree->right,outfile,indent+2);
6433 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6434 printTypeChain(tree->ftype,outfile);
6435 fprintf(outfile,")\n");
6436 ast_print(tree->left,outfile,indent+2);
6437 ast_print(tree->right,outfile,indent+2);
6439 /*------------------------------------------------------------------*/
6440 /*----------------------------*/
6442 /*----------------------------*/
6444 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6445 printTypeChain(tree->ftype,outfile);
6446 fprintf(outfile,")\n");
6447 ast_print(tree->left,outfile,indent+2);
6448 ast_print(tree->right,outfile,indent+2);
6450 /*------------------------------------------------------------------*/
6451 /*----------------------------*/
6453 /*----------------------------*/
6455 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6456 printTypeChain(tree->ftype,outfile);
6457 fprintf(outfile,")\n");
6458 ast_print(tree->left,outfile,indent+2);
6459 ast_print(tree->right,outfile,indent+2);
6461 /*------------------------------------------------------------------*/
6462 /*----------------------------*/
6463 /* straight assignemnt */
6464 /*----------------------------*/
6466 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6467 printTypeChain(tree->ftype,outfile);
6468 fprintf(outfile,")\n");
6469 ast_print(tree->left,outfile,indent+2);
6470 ast_print(tree->right,outfile,indent+2);
6472 /*------------------------------------------------------------------*/
6473 /*----------------------------*/
6474 /* comma operator */
6475 /*----------------------------*/
6477 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6478 printTypeChain(tree->ftype,outfile);
6479 fprintf(outfile,")\n");
6480 ast_print(tree->left,outfile,indent+2);
6481 ast_print(tree->right,outfile,indent+2);
6483 /*------------------------------------------------------------------*/
6484 /*----------------------------*/
6486 /*----------------------------*/
6489 fprintf(outfile,"CALL (%p) type (",tree);
6490 printTypeChain(tree->ftype,outfile);
6491 fprintf(outfile,")\n");
6492 ast_print(tree->left,outfile,indent+2);
6493 ast_print(tree->right,outfile,indent+2);
6496 fprintf(outfile,"PARMS\n");
6497 ast_print(tree->left,outfile,indent+2);
6498 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6499 ast_print(tree->right,outfile,indent+2);
6502 /*------------------------------------------------------------------*/
6503 /*----------------------------*/
6504 /* return statement */
6505 /*----------------------------*/
6507 fprintf(outfile,"RETURN (%p) type (",tree);
6509 printTypeChain(tree->right->ftype,outfile);
6511 fprintf(outfile,")\n");
6512 ast_print(tree->right,outfile,indent+2);
6514 /*------------------------------------------------------------------*/
6515 /*----------------------------*/
6516 /* label statement */
6517 /*----------------------------*/
6519 fprintf(outfile,"LABEL (%p)\n",tree);
6520 ast_print(tree->left,outfile,indent+2);
6521 ast_print(tree->right,outfile,indent);
6523 /*------------------------------------------------------------------*/
6524 /*----------------------------*/
6525 /* switch statement */
6526 /*----------------------------*/
6530 fprintf(outfile,"SWITCH (%p) ",tree);
6531 ast_print(tree->left,outfile,0);
6532 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6533 INDENT(indent+2,outfile);
6534 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6535 (int) floatFromVal(val),
6536 tree->values.switchVals.swNum,
6537 (int) floatFromVal(val));
6539 ast_print(tree->right,outfile,indent);
6542 /*------------------------------------------------------------------*/
6543 /*----------------------------*/
6545 /*----------------------------*/
6547 fprintf(outfile,"IF (%p) \n",tree);
6548 ast_print(tree->left,outfile,indent+2);
6549 if (tree->trueLabel) {
6550 INDENT(indent+2,outfile);
6551 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6553 if (tree->falseLabel) {
6554 INDENT(indent+2,outfile);
6555 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6557 ast_print(tree->right,outfile,indent+2);
6559 /*----------------------------*/
6560 /* goto Statement */
6561 /*----------------------------*/
6563 fprintf(outfile,"GOTO (%p) \n",tree);
6564 ast_print(tree->left,outfile,indent+2);
6565 fprintf(outfile,"\n");
6567 /*------------------------------------------------------------------*/
6568 /*----------------------------*/
6570 /*----------------------------*/
6572 fprintf(outfile,"FOR (%p) \n",tree);
6573 if (AST_FOR( tree, initExpr)) {
6574 INDENT(indent+2,outfile);
6575 fprintf(outfile,"INIT EXPR ");
6576 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6578 if (AST_FOR( tree, condExpr)) {
6579 INDENT(indent+2,outfile);
6580 fprintf(outfile,"COND EXPR ");
6581 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6583 if (AST_FOR( tree, loopExpr)) {
6584 INDENT(indent+2,outfile);
6585 fprintf(outfile,"LOOP EXPR ");
6586 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6588 fprintf(outfile,"FOR LOOP BODY \n");
6589 ast_print(tree->left,outfile,indent+2);
6592 fprintf(outfile,"CRITICAL (%p) \n",tree);
6593 ast_print(tree->left,outfile,indent+2);
6601 ast_print(t,stdout,0);
6606 /*-----------------------------------------------------------------*/
6607 /* astErrors : returns non-zero if errors present in tree */
6608 /*-----------------------------------------------------------------*/
6609 int astErrors(ast *t)
6618 if (t->type == EX_VALUE
6619 && t->opval.val->sym
6620 && t->opval.val->sym->undefined)
6623 errors += astErrors(t->left);
6624 errors += astErrors(t->right);