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 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->etype) :
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 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 return cexpr->opval.val;
1474 /*-----------------------------------------------------------------*/
1475 /* isLabelInAst - will return true if a given label is found */
1476 /*-----------------------------------------------------------------*/
1478 isLabelInAst (symbol * label, ast * tree)
1480 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1483 if (IS_AST_OP (tree) &&
1484 tree->opval.op == LABEL &&
1485 isSymbolEqual (AST_SYMBOL (tree->left), label))
1488 return isLabelInAst (label, tree->right) &&
1489 isLabelInAst (label, tree->left);
1493 /*-----------------------------------------------------------------*/
1494 /* isLoopCountable - return true if the loop count can be determi- */
1495 /* -ned at compile time . */
1496 /*-----------------------------------------------------------------*/
1498 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1499 symbol ** sym, ast ** init, ast ** end)
1502 /* the loop is considered countable if the following
1503 conditions are true :-
1505 a) initExpr :- <sym> = <const>
1506 b) condExpr :- <sym> < <const1>
1507 c) loopExpr :- <sym> ++
1510 /* first check the initExpr */
1511 if (IS_AST_OP (initExpr) &&
1512 initExpr->opval.op == '=' && /* is assignment */
1513 IS_AST_SYM_VALUE (initExpr->left))
1514 { /* left is a symbol */
1516 *sym = AST_SYMBOL (initExpr->left);
1517 *init = initExpr->right;
1522 /* for now the symbol has to be of
1524 if (!IS_INTEGRAL ((*sym)->type))
1527 /* now check condExpr */
1528 if (IS_AST_OP (condExpr))
1531 switch (condExpr->opval.op)
1534 if (IS_AST_SYM_VALUE (condExpr->left) &&
1535 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1536 IS_AST_LIT_VALUE (condExpr->right))
1538 *end = condExpr->right;
1544 if (IS_AST_OP (condExpr->left) &&
1545 condExpr->left->opval.op == '>' &&
1546 IS_AST_LIT_VALUE (condExpr->left->right) &&
1547 IS_AST_SYM_VALUE (condExpr->left->left) &&
1548 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1551 *end = newNode ('+', condExpr->left->right,
1552 newAst_VALUE (constVal ("1")));
1565 /* check loop expression is of the form <sym>++ */
1566 if (!IS_AST_OP (loopExpr))
1569 /* check if <sym> ++ */
1570 if (loopExpr->opval.op == INC_OP)
1576 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1577 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1584 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1585 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1593 if (loopExpr->opval.op == ADD_ASSIGN)
1596 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1597 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1598 IS_AST_LIT_VALUE (loopExpr->right) &&
1599 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1607 /*-----------------------------------------------------------------*/
1608 /* astHasVolatile - returns true if ast contains any volatile */
1609 /*-----------------------------------------------------------------*/
1611 astHasVolatile (ast * tree)
1616 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1619 if (IS_AST_OP (tree))
1620 return astHasVolatile (tree->left) ||
1621 astHasVolatile (tree->right);
1626 /*-----------------------------------------------------------------*/
1627 /* astHasPointer - return true if the ast contains any ptr variable */
1628 /*-----------------------------------------------------------------*/
1630 astHasPointer (ast * tree)
1635 if (IS_AST_LINK (tree))
1638 /* if we hit an array expression then check
1639 only the left side */
1640 if (IS_AST_OP (tree) && tree->opval.op == '[')
1641 return astHasPointer (tree->left);
1643 if (IS_AST_VALUE (tree))
1644 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1646 return astHasPointer (tree->left) ||
1647 astHasPointer (tree->right);
1651 /*-----------------------------------------------------------------*/
1652 /* astHasSymbol - return true if the ast has the given symbol */
1653 /*-----------------------------------------------------------------*/
1655 astHasSymbol (ast * tree, symbol * sym)
1657 if (!tree || IS_AST_LINK (tree))
1660 if (IS_AST_VALUE (tree))
1662 if (IS_AST_SYM_VALUE (tree))
1663 return isSymbolEqual (AST_SYMBOL (tree), sym);
1668 return astHasSymbol (tree->left, sym) ||
1669 astHasSymbol (tree->right, sym);
1672 /*-----------------------------------------------------------------*/
1673 /* astHasDeref - return true if the ast has an indirect access */
1674 /*-----------------------------------------------------------------*/
1676 astHasDeref (ast * tree)
1678 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1681 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1683 return astHasDeref (tree->left) || astHasDeref (tree->right);
1686 /*-----------------------------------------------------------------*/
1687 /* isConformingBody - the loop body has to conform to a set of rules */
1688 /* for the loop to be considered reversible read on for rules */
1689 /*-----------------------------------------------------------------*/
1691 isConformingBody (ast * pbody, symbol * sym, ast * body)
1694 /* we are going to do a pre-order traversal of the
1695 tree && check for the following conditions. (essentially
1696 a set of very shallow tests )
1697 a) the sym passed does not participate in
1698 any arithmetic operation
1699 b) There are no function calls
1700 c) all jumps are within the body
1701 d) address of loop control variable not taken
1702 e) if an assignment has a pointer on the
1703 left hand side make sure right does not have
1704 loop control variable */
1706 /* if we reach the end or a leaf then true */
1707 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1710 /* if anything else is "volatile" */
1711 if (IS_VOLATILE (TETYPE (pbody)))
1714 /* we will walk the body in a pre-order traversal for
1716 switch (pbody->opval.op)
1718 /*------------------------------------------------------------------*/
1720 // if the loopvar is used as an index
1721 /* array op is commutative -- must check both left & right */
1722 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1725 return isConformingBody (pbody->right, sym, body)
1726 && isConformingBody (pbody->left, sym, body);
1728 /*------------------------------------------------------------------*/
1733 /*------------------------------------------------------------------*/
1737 /* sure we are not sym is not modified */
1739 IS_AST_SYM_VALUE (pbody->left) &&
1740 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1744 IS_AST_SYM_VALUE (pbody->right) &&
1745 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1750 /*------------------------------------------------------------------*/
1752 case '*': /* can be unary : if right is null then unary operation */
1757 /* if right is NULL then unary operation */
1758 /*------------------------------------------------------------------*/
1759 /*----------------------------*/
1761 /*----------------------------*/
1764 if (IS_AST_SYM_VALUE (pbody->left) &&
1765 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1768 return isConformingBody (pbody->left, sym, body);
1772 if (astHasSymbol (pbody->left, sym) ||
1773 astHasSymbol (pbody->right, sym))
1778 /*------------------------------------------------------------------*/
1789 if (IS_AST_SYM_VALUE (pbody->left) &&
1790 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1793 if (IS_AST_SYM_VALUE (pbody->right) &&
1794 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1797 return isConformingBody (pbody->left, sym, body) &&
1798 isConformingBody (pbody->right, sym, body);
1806 if (IS_AST_SYM_VALUE (pbody->left) &&
1807 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1809 return isConformingBody (pbody->left, sym, body);
1811 /*------------------------------------------------------------------*/
1823 case SIZEOF: /* evaluate wihout code generation */
1825 if (IS_AST_SYM_VALUE (pbody->left) &&
1826 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1829 if (IS_AST_SYM_VALUE (pbody->right) &&
1830 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1833 return isConformingBody (pbody->left, sym, body) &&
1834 isConformingBody (pbody->right, sym, body);
1836 /*------------------------------------------------------------------*/
1839 /* if left has a pointer & right has loop
1840 control variable then we cannot */
1841 if (astHasPointer (pbody->left) &&
1842 astHasSymbol (pbody->right, sym))
1844 if (astHasVolatile (pbody->left))
1847 if (IS_AST_SYM_VALUE (pbody->left)) {
1848 // if the loopvar has an assignment
1849 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1851 // if the loopvar is used in another (maybe conditional) block
1852 if (astHasSymbol (pbody->right, sym) &&
1853 (pbody->level >= body->level)) {
1858 if (astHasVolatile (pbody->left))
1861 if (astHasDeref(pbody->right)) return FALSE;
1863 return isConformingBody (pbody->left, sym, body) &&
1864 isConformingBody (pbody->right, sym, body);
1875 assert ("Parser should not have generated this\n");
1877 /*------------------------------------------------------------------*/
1878 /*----------------------------*/
1879 /* comma operator */
1880 /*----------------------------*/
1882 return isConformingBody (pbody->left, sym, body) &&
1883 isConformingBody (pbody->right, sym, body);
1885 /*------------------------------------------------------------------*/
1886 /*----------------------------*/
1888 /*----------------------------*/
1890 /* if local & not passed as paramater then ok */
1891 if (sym->level && !astHasSymbol(pbody->right,sym))
1895 /*------------------------------------------------------------------*/
1896 /*----------------------------*/
1897 /* return statement */
1898 /*----------------------------*/
1903 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1908 if (astHasSymbol (pbody->left, sym))
1915 return isConformingBody (pbody->left, sym, body) &&
1916 isConformingBody (pbody->right, sym, body);
1922 /*-----------------------------------------------------------------*/
1923 /* isLoopReversible - takes a for loop as input && returns true */
1924 /* if the for loop is reversible. If yes will set the value of */
1925 /* the loop control var & init value & termination value */
1926 /*-----------------------------------------------------------------*/
1928 isLoopReversible (ast * loop, symbol ** loopCntrl,
1929 ast ** init, ast ** end)
1931 /* if option says don't do it then don't */
1932 if (optimize.noLoopReverse)
1934 /* there are several tests to determine this */
1936 /* for loop has to be of the form
1937 for ( <sym> = <const1> ;
1938 [<sym> < <const2>] ;
1939 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1941 if (!isLoopCountable (AST_FOR (loop, initExpr),
1942 AST_FOR (loop, condExpr),
1943 AST_FOR (loop, loopExpr),
1944 loopCntrl, init, end))
1947 /* now do some serious checking on the body of the loop
1950 return isConformingBody (loop->left, *loopCntrl, loop->left);
1954 /*-----------------------------------------------------------------*/
1955 /* replLoopSym - replace the loop sym by loop sym -1 */
1956 /*-----------------------------------------------------------------*/
1958 replLoopSym (ast * body, symbol * sym)
1961 if (!body || IS_AST_LINK (body))
1964 if (IS_AST_SYM_VALUE (body))
1967 if (isSymbolEqual (AST_SYMBOL (body), sym))
1971 body->opval.op = '-';
1972 body->left = newAst_VALUE (symbolVal (sym));
1973 body->right = newAst_VALUE (constVal ("1"));
1981 replLoopSym (body->left, sym);
1982 replLoopSym (body->right, sym);
1986 /*-----------------------------------------------------------------*/
1987 /* reverseLoop - do the actual loop reversal */
1988 /*-----------------------------------------------------------------*/
1990 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1994 /* create the following tree
1999 if (sym) goto for_continue ;
2002 /* put it together piece by piece */
2003 rloop = newNode (NULLOP,
2004 createIf (newAst_VALUE (symbolVal (sym)),
2006 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2009 newAst_VALUE (symbolVal (sym)),
2012 replLoopSym (loop->left, sym);
2013 setAstLineno (rloop, init->lineno);
2015 rloop = newNode (NULLOP,
2017 newAst_VALUE (symbolVal (sym)),
2018 newNode ('-', end, init)),
2019 createLabel (AST_FOR (loop, continueLabel),
2023 newNode (SUB_ASSIGN,
2024 newAst_VALUE (symbolVal (sym)),
2025 newAst_VALUE (constVal ("1"))),
2028 rloop->lineno=init->lineno;
2029 return decorateType (rloop, RESULT_TYPE_NONE);
2033 /*-----------------------------------------------------------------*/
2034 /* searchLitOp - search tree (*ops only) for an ast with literal */
2035 /*-----------------------------------------------------------------*/
2037 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2041 if (tree && optimize.global_cse)
2043 /* is there a literal operand? */
2045 IS_AST_OP(tree->right) &&
2046 tree->right->right &&
2047 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2049 if (IS_LITERAL (RTYPE (tree->right)) !=
2050 IS_LITERAL (LTYPE (tree->right)))
2052 tree->right->decorated = 0;
2053 tree->decorated = 0;
2057 ret = searchLitOp (tree->right, parent, ops);
2062 IS_AST_OP(tree->left) &&
2063 tree->left->right &&
2064 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2066 if (IS_LITERAL (RTYPE (tree->left)) !=
2067 IS_LITERAL (LTYPE (tree->left)))
2069 tree->left->decorated = 0;
2070 tree->decorated = 0;
2074 ret = searchLitOp (tree->left, parent, ops);
2082 /*-----------------------------------------------------------------*/
2083 /* getResultFromType */
2084 /*-----------------------------------------------------------------*/
2086 getResultTypeFromType (sym_link *type)
2088 /* type = getSpec (type); */
2090 return RESULT_TYPE_BIT;
2091 if (IS_BITFIELD (type))
2093 int blen = SPEC_BLEN (type);
2096 return RESULT_TYPE_BIT;
2098 return RESULT_TYPE_CHAR;
2099 return RESULT_TYPE_INT;
2102 return RESULT_TYPE_CHAR;
2105 return RESULT_TYPE_INT;
2106 return RESULT_TYPE_OTHER;
2109 /*-----------------------------------------------------------------*/
2110 /* addCast - adds casts to a type specified by RESULT_TYPE */
2111 /*-----------------------------------------------------------------*/
2113 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2116 bool upCasted = FALSE;
2120 case RESULT_TYPE_NONE:
2121 /* if thing smaller than int must be promoted to int */
2123 getSize (tree->etype) >= INTSIZE)
2124 /* promotion not necessary or already an int */
2126 /* char and bits: promote to int */
2127 newLink = newIntLink();
2130 case RESULT_TYPE_BIT:
2132 /* already an int */
2133 bitsForType (tree->etype) >= 16 ||
2134 /* bit to bit operation: don't promote, the code generators
2135 hopefully know everything about promotion rules */
2136 bitsForType (tree->etype) == 1)
2138 newLink = newIntLink();
2141 case RESULT_TYPE_CHAR:
2142 if (IS_CHAR (tree->etype) ||
2143 IS_FLOAT(tree->etype) ||
2144 IS_FIXED(tree->etype))
2146 newLink = newCharLink();
2148 case RESULT_TYPE_INT:
2150 if (getSize (tree->etype) > INTSIZE)
2152 /* warn ("Loosing significant digits"); */
2156 /* char: promote to int */
2158 getSize (tree->etype) >= INTSIZE)
2160 newLink = newIntLink();
2163 case RESULT_TYPE_OTHER:
2166 /* return type is long, float: promote char to int */
2167 if (getSize (tree->etype) >= INTSIZE)
2169 newLink = newIntLink();
2175 tree->decorated = 0;
2176 tree = newNode (CAST, newAst_LINK (newLink), tree);
2177 tree->lineno = tree->right->lineno;
2178 /* keep unsigned type during cast to smaller type,
2179 but not when promoting from char to int */
2181 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2182 return decorateType (tree, resultType);
2185 /*-----------------------------------------------------------------*/
2186 /* resultTypePropagate - decides if resultType can be propagated */
2187 /*-----------------------------------------------------------------*/
2189 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2191 switch (tree->opval.op)
2210 return RESULT_TYPE_NONE;
2214 return RESULT_TYPE_IFX;
2216 return RESULT_TYPE_NONE;
2220 /*-----------------------------------------------------------------*/
2221 /* getLeftResultType - gets type from left branch for propagation */
2222 /*-----------------------------------------------------------------*/
2224 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2226 switch (tree->opval.op)
2230 if (IS_PTR (LTYPE (tree)))
2231 return RESULT_TYPE_NONE;
2233 return getResultTypeFromType (LETYPE (tree));
2235 if (IS_PTR (currFunc->type->next))
2236 return RESULT_TYPE_NONE;
2238 return getResultTypeFromType (currFunc->type->next);
2240 if (!IS_ARRAY (LTYPE (tree)))
2242 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2243 return RESULT_TYPE_CHAR;
2250 /*--------------------------------------------------------------------*/
2251 /* decorateType - compute type for this tree, also does type checking.*/
2252 /* This is done bottom up, since type has to flow upwards. */
2253 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2254 /* result is a char and the operand(s) are int's. */
2255 /* It also does constant folding, and parameter checking. */
2256 /*--------------------------------------------------------------------*/
2258 decorateType (ast * tree, RESULT_TYPE resultType)
2262 RESULT_TYPE resultTypeProp;
2267 /* if already has type then do nothing */
2268 if (tree->decorated)
2271 tree->decorated = 1;
2274 /* print the line */
2275 /* if not block & function */
2276 if (tree->type == EX_OP &&
2277 (tree->opval.op != FUNCTION &&
2278 tree->opval.op != BLOCK &&
2279 tree->opval.op != NULLOP))
2281 filename = tree->filename;
2282 lineno = tree->lineno;
2286 /* if any child is an error | this one is an error do nothing */
2287 if (tree->isError ||
2288 (tree->left && tree->left->isError) ||
2289 (tree->right && tree->right->isError))
2292 /*------------------------------------------------------------------*/
2293 /*----------------------------*/
2294 /* leaf has been reached */
2295 /*----------------------------*/
2296 lineno=tree->lineno;
2297 /* if this is of type value */
2298 /* just get the type */
2299 if (tree->type == EX_VALUE)
2302 if (IS_LITERAL (tree->opval.val->etype))
2305 /* if this is a character array then declare it */
2306 if (IS_ARRAY (tree->opval.val->type))
2307 tree->opval.val = stringToSymbol (tree->opval.val);
2309 /* otherwise just copy the type information */
2310 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2314 if (tree->opval.val->sym)
2316 /* if the undefined flag is set then give error message */
2317 if (tree->opval.val->sym->undefined)
2319 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2321 TTYPE (tree) = TETYPE (tree) =
2322 tree->opval.val->type = tree->opval.val->sym->type =
2323 tree->opval.val->etype = tree->opval.val->sym->etype =
2324 copyLinkChain (INTTYPE);
2329 /* if impilicit i.e. struct/union member then no type */
2330 if (tree->opval.val->sym->implicit)
2331 TTYPE (tree) = TETYPE (tree) = NULL;
2336 /* else copy the type */
2337 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2339 /* and mark it as referenced */
2340 tree->opval.val->sym->isref = 1;
2348 /* if type link for the case of cast */
2349 if (tree->type == EX_LINK)
2351 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2359 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2361 if (tree->left && tree->left->type == EX_OPERAND
2362 && (tree->left->opval.op == INC_OP
2363 || tree->left->opval.op == DEC_OP)
2364 && tree->left->left)
2366 tree->left->right = tree->left->left;
2367 tree->left->left = NULL;
2369 if (tree->right && tree->right->type == EX_OPERAND
2370 && (tree->right->opval.op == INC_OP
2371 || tree->right->opval.op == DEC_OP)
2372 && tree->right->left)
2374 tree->right->right = tree->right->left;
2375 tree->right->left = NULL;
2380 /* Before decorating the left branch we've to decide in dependence
2381 upon tree->opval.op, if resultType can be propagated */
2382 resultTypeProp = resultTypePropagate (tree, resultType);
2384 if (tree->opval.op == '?')
2385 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2387 dtl = decorateType (tree->left, resultTypeProp);
2389 /* if an array node, we may need to swap branches */
2390 if (tree->opval.op == '[')
2392 /* determine which is the array & which the index */
2393 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2394 IS_INTEGRAL (LTYPE (tree)))
2396 ast *tempTree = tree->left;
2397 tree->left = tree->right;
2398 tree->right = tempTree;
2402 /* After decorating the left branch there's type information available
2403 in tree->left->?type. If the op is e.g. '=' we extract the type
2404 information from there and propagate it to the right branch. */
2405 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2407 switch (tree->opval.op)
2410 /* delay right side for '?' operator since conditional macro
2411 expansions might rely on this */
2415 /* decorate right side for CALL (parameter list) in processParms();
2416 there is resultType available */
2420 dtr = decorateType (tree->right, resultTypeProp);
2424 /* this is to take care of situations
2425 when the tree gets rewritten */
2426 if (dtl != tree->left)
2428 if (dtr != tree->right)
2430 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2434 /* depending on type of operator do */
2436 switch (tree->opval.op)
2438 /*------------------------------------------------------------------*/
2439 /*----------------------------*/
2441 /*----------------------------*/
2444 /* first check if this is a array or a pointer */
2445 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2447 werror (E_NEED_ARRAY_PTR, "[]");
2448 goto errorTreeReturn;
2451 /* check if the type of the idx */
2452 if (!IS_INTEGRAL (RTYPE (tree)))
2454 werror (E_IDX_NOT_INT);
2455 goto errorTreeReturn;
2458 /* if the left is an rvalue then error */
2461 werror (E_LVALUE_REQUIRED, "array access");
2462 goto errorTreeReturn;
2465 if (IS_LITERAL (RTYPE (tree)))
2467 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2468 int arraySize = DCL_ELEM (LTYPE (tree));
2469 if (arraySize && arrayIndex >= arraySize)
2471 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2476 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2479 /*------------------------------------------------------------------*/
2480 /*----------------------------*/
2482 /*----------------------------*/
2484 /* if this is not a structure */
2485 if (!IS_STRUCT (LTYPE (tree)))
2487 werror (E_STRUCT_UNION, ".");
2488 goto errorTreeReturn;
2490 TTYPE (tree) = structElemType (LTYPE (tree),
2491 (tree->right->type == EX_VALUE ?
2492 tree->right->opval.val : NULL));
2493 TETYPE (tree) = getSpec (TTYPE (tree));
2496 /*------------------------------------------------------------------*/
2497 /*----------------------------*/
2498 /* struct/union pointer */
2499 /*----------------------------*/
2501 /* if not pointer to a structure */
2502 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2504 werror (E_PTR_REQD);
2505 goto errorTreeReturn;
2508 if (!IS_STRUCT (LTYPE (tree)->next))
2510 werror (E_STRUCT_UNION, "->");
2511 goto errorTreeReturn;
2514 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2515 (tree->right->type == EX_VALUE ?
2516 tree->right->opval.val : NULL));
2517 TETYPE (tree) = getSpec (TTYPE (tree));
2519 /* adjust the storage class */
2520 switch (DCL_TYPE(tree->left->ftype)) {
2522 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2525 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2528 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2531 SPEC_SCLS (TETYPE (tree)) = 0;
2534 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2537 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2540 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2543 SPEC_SCLS (TETYPE (tree)) = 0;
2550 /* This breaks with extern declarations, bitfields, and perhaps other */
2551 /* cases (gcse). Let's leave this optimization disabled for now and */
2552 /* ponder if there's a safe way to do this. -- EEP */
2554 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2555 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2557 /* If defined struct type at addr var
2558 then rewrite (&struct var)->member
2560 and define membertype at (addr+offsetof(struct var,member)) temp
2563 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2564 AST_SYMBOL(tree->right));
2566 sym = newSymbol(genSymName (0), 0);
2567 sym->type = TTYPE (tree);
2568 sym->etype = getSpec(sym->type);
2569 sym->lineDef = tree->lineno;
2572 SPEC_STAT (sym->etype) = 1;
2573 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2575 SPEC_ABSA(sym->etype) = 1;
2576 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2579 AST_VALUE (tree) = symbolVal(sym);
2582 tree->type = EX_VALUE;
2590 /*------------------------------------------------------------------*/
2591 /*----------------------------*/
2592 /* ++/-- operation */
2593 /*----------------------------*/
2597 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2598 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2599 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2600 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2609 /*------------------------------------------------------------------*/
2610 /*----------------------------*/
2612 /*----------------------------*/
2613 case '&': /* can be unary */
2614 /* if right is NULL then unary operation */
2615 if (tree->right) /* not an unary operation */
2618 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2620 werror (E_BITWISE_OP);
2621 werror (W_CONTINUE, "left & right types are ");
2622 printTypeChain (LTYPE (tree), stderr);
2623 fprintf (stderr, ",");
2624 printTypeChain (RTYPE (tree), stderr);
2625 fprintf (stderr, "\n");
2626 goto errorTreeReturn;
2629 /* if they are both literal */
2630 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2632 tree->type = EX_VALUE;
2633 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2634 valFromType (RETYPE (tree)), '&');
2636 tree->right = tree->left = NULL;
2637 TETYPE (tree) = tree->opval.val->etype;
2638 TTYPE (tree) = tree->opval.val->type;
2642 /* see if this is a GETHBIT operation if yes
2645 ast *otree = optimizeGetHbit (tree, resultType);
2648 return decorateType (otree, RESULT_TYPE_NONE);
2651 /* see if this is a GETABIT operation if yes
2654 ast *otree = optimizeGetAbit (tree, resultType);
2657 return decorateType (otree, RESULT_TYPE_NONE);
2660 /* see if this is a GETBYTE operation if yes
2663 ast *otree = optimizeGetByte (tree, resultType);
2666 return decorateType (otree, RESULT_TYPE_NONE);
2669 /* see if this is a GETWORD operation if yes
2672 ast *otree = optimizeGetWord (tree, resultType);
2675 return decorateType (otree, RESULT_TYPE_NONE);
2678 /* if left is a literal exchange left & right */
2679 if (IS_LITERAL (LTYPE (tree)))
2681 ast *tTree = tree->left;
2682 tree->left = tree->right;
2683 tree->right = tTree;
2686 /* if right is a literal and */
2687 /* we can find a 2nd literal in an and-tree then */
2688 /* rearrange the tree */
2689 if (IS_LITERAL (RTYPE (tree)))
2692 ast *litTree = searchLitOp (tree, &parent, "&");
2696 ast *tTree = litTree->left;
2697 litTree->left = tree->right;
2698 tree->right = tTree;
2699 /* both operands in litTree are literal now */
2700 decorateType (parent, resultType);
2704 LRVAL (tree) = RRVAL (tree) = 1;
2706 TTYPE (tree) = computeType (LTYPE (tree),
2710 TETYPE (tree) = getSpec (TTYPE (tree));
2715 /*------------------------------------------------------------------*/
2716 /*----------------------------*/
2718 /*----------------------------*/
2719 p = newLink (DECLARATOR);
2720 /* if bit field then error */
2721 if (IS_BITVAR (tree->left->etype))
2723 werror (E_ILLEGAL_ADDR, "address of bit variable");
2724 goto errorTreeReturn;
2727 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2729 werror (E_ILLEGAL_ADDR, "address of register variable");
2730 goto errorTreeReturn;
2733 if (IS_FUNC (LTYPE (tree)))
2735 // this ought to be ignored
2736 return (tree->left);
2739 if (IS_LITERAL(LTYPE(tree)))
2741 werror (E_ILLEGAL_ADDR, "address of literal");
2742 goto errorTreeReturn;
2747 werror (E_LVALUE_REQUIRED, "address of");
2748 goto errorTreeReturn;
2751 DCL_TYPE (p) = POINTER;
2752 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2753 DCL_TYPE (p) = CPOINTER;
2754 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2755 DCL_TYPE (p) = FPOINTER;
2756 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2757 DCL_TYPE (p) = PPOINTER;
2758 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2759 DCL_TYPE (p) = IPOINTER;
2760 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2761 DCL_TYPE (p) = EEPPOINTER;
2762 else if (SPEC_OCLS(tree->left->etype))
2763 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2765 DCL_TYPE (p) = POINTER;
2767 if (IS_AST_SYM_VALUE (tree->left))
2769 AST_SYMBOL (tree->left)->addrtaken = 1;
2770 AST_SYMBOL (tree->left)->allocreq = 1;
2773 p->next = LTYPE (tree);
2775 TETYPE (tree) = getSpec (TTYPE (tree));
2780 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2781 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2783 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2784 AST_SYMBOL(tree->left->right));
2785 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2786 valueFromLit(element->offset));
2789 tree->type = EX_VALUE;
2790 tree->values.literalFromCast = 1;
2796 /*------------------------------------------------------------------*/
2797 /*----------------------------*/
2799 /*----------------------------*/
2801 /* if the rewrite succeeds then don't go any further */
2803 ast *wtree = optimizeRRCRLC (tree);
2805 return decorateType (wtree, RESULT_TYPE_NONE);
2807 wtree = optimizeSWAP (tree);
2809 return decorateType (wtree, RESULT_TYPE_NONE);
2812 /* if left is a literal exchange left & right */
2813 if (IS_LITERAL (LTYPE (tree)))
2815 ast *tTree = tree->left;
2816 tree->left = tree->right;
2817 tree->right = tTree;
2820 /* if right is a literal and */
2821 /* we can find a 2nd literal in an or-tree then */
2822 /* rearrange the tree */
2823 if (IS_LITERAL (RTYPE (tree)))
2826 ast *litTree = searchLitOp (tree, &parent, "|");
2830 ast *tTree = litTree->left;
2831 litTree->left = tree->right;
2832 tree->right = tTree;
2833 /* both operands in tTree are literal now */
2834 decorateType (parent, resultType);
2839 /*------------------------------------------------------------------*/
2840 /*----------------------------*/
2842 /*----------------------------*/
2844 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2846 werror (E_BITWISE_OP);
2847 werror (W_CONTINUE, "left & right types are ");
2848 printTypeChain (LTYPE (tree), stderr);
2849 fprintf (stderr, ",");
2850 printTypeChain (RTYPE (tree), stderr);
2851 fprintf (stderr, "\n");
2852 goto errorTreeReturn;
2855 /* if they are both literal then rewrite the tree */
2856 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2858 tree->type = EX_VALUE;
2859 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2860 valFromType (RETYPE (tree)),
2862 tree->right = tree->left = NULL;
2863 TETYPE (tree) = tree->opval.val->etype;
2864 TTYPE (tree) = tree->opval.val->type;
2868 /* if left is a literal exchange left & right */
2869 if (IS_LITERAL (LTYPE (tree)))
2871 ast *tTree = tree->left;
2872 tree->left = tree->right;
2873 tree->right = tTree;
2876 /* if right is a literal and */
2877 /* we can find a 2nd literal in a xor-tree then */
2878 /* rearrange the tree */
2879 if (IS_LITERAL (RTYPE (tree)) &&
2880 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2883 ast *litTree = searchLitOp (tree, &parent, "^");
2887 ast *tTree = litTree->left;
2888 litTree->left = tree->right;
2889 tree->right = tTree;
2890 /* both operands in litTree are literal now */
2891 decorateType (parent, resultType);
2895 LRVAL (tree) = RRVAL (tree) = 1;
2897 TTYPE (tree) = computeType (LTYPE (tree),
2901 TETYPE (tree) = getSpec (TTYPE (tree));
2905 /*------------------------------------------------------------------*/
2906 /*----------------------------*/
2908 /*----------------------------*/
2910 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2912 werror (E_INVALID_OP, "divide");
2913 goto errorTreeReturn;
2915 /* if they are both literal then */
2916 /* rewrite the tree */
2917 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2919 tree->type = EX_VALUE;
2920 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2921 valFromType (RETYPE (tree)));
2922 tree->right = tree->left = NULL;
2923 TETYPE (tree) = getSpec (TTYPE (tree) =
2924 tree->opval.val->type);
2928 LRVAL (tree) = RRVAL (tree) = 1;
2930 TETYPE (tree) = getSpec (TTYPE (tree) =
2931 computeType (LTYPE (tree),
2936 /* if right is a literal and */
2937 /* left is also a division by a literal then */
2938 /* rearrange the tree */
2939 if (IS_LITERAL (RTYPE (tree))
2940 /* avoid infinite loop */
2941 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2944 ast *litTree = searchLitOp (tree, &parent, "/");
2947 if (IS_LITERAL (RTYPE (litTree)))
2951 litTree->right = newNode ('*',
2953 copyAst (tree->right));
2954 litTree->right->lineno = tree->lineno;
2956 tree->right->opval.val = constVal ("1");
2957 decorateType (parent, resultType);
2961 /* litTree->left is literal: no gcse possible.
2962 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2963 this would cause an infinit loop. */
2964 parent->decorated = 1;
2965 decorateType (litTree, resultType);
2972 /*------------------------------------------------------------------*/
2973 /*----------------------------*/
2975 /*----------------------------*/
2977 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2979 werror (E_BITWISE_OP);
2980 werror (W_CONTINUE, "left & right types are ");
2981 printTypeChain (LTYPE (tree), stderr);
2982 fprintf (stderr, ",");
2983 printTypeChain (RTYPE (tree), stderr);
2984 fprintf (stderr, "\n");
2985 goto errorTreeReturn;
2987 /* if they are both literal then */
2988 /* rewrite the tree */
2989 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2991 tree->type = EX_VALUE;
2992 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2993 valFromType (RETYPE (tree)));
2994 tree->right = tree->left = NULL;
2995 TETYPE (tree) = getSpec (TTYPE (tree) =
2996 tree->opval.val->type);
2999 LRVAL (tree) = RRVAL (tree) = 1;
3000 TETYPE (tree) = getSpec (TTYPE (tree) =
3001 computeType (LTYPE (tree),
3007 /*------------------------------------------------------------------*/
3008 /*----------------------------*/
3009 /* address dereference */
3010 /*----------------------------*/
3011 case '*': /* can be unary : if right is null then unary operation */
3014 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3016 werror (E_PTR_REQD);
3017 goto errorTreeReturn;
3022 werror (E_LVALUE_REQUIRED, "pointer deref");
3023 goto errorTreeReturn;
3025 if (IS_ADDRESS_OF_OP(tree->left))
3027 /* replace *&obj with obj */
3028 return tree->left->left;
3030 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3031 TETYPE (tree) = getSpec (TTYPE (tree));
3032 /* adjust the storage class */
3033 switch (DCL_TYPE(tree->left->ftype)) {
3035 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3038 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3041 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3044 SPEC_SCLS (TETYPE (tree)) = 0;
3047 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3050 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3053 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3056 SPEC_SCLS (TETYPE (tree)) = 0;
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3067 /* multiplication */
3068 /*----------------------------*/
3069 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3071 werror (E_INVALID_OP, "multiplication");
3072 goto errorTreeReturn;
3075 /* if they are both literal then */
3076 /* rewrite the tree */
3077 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3079 tree->type = EX_VALUE;
3080 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3081 valFromType (RETYPE (tree)));
3082 tree->right = tree->left = NULL;
3083 TETYPE (tree) = getSpec (TTYPE (tree) =
3084 tree->opval.val->type);
3088 /* if left is a literal exchange left & right */
3089 if (IS_LITERAL (LTYPE (tree)))
3091 ast *tTree = tree->left;
3092 tree->left = tree->right;
3093 tree->right = tTree;
3096 /* if right is a literal and */
3097 /* we can find a 2nd literal in a mul-tree then */
3098 /* rearrange the tree */
3099 if (IS_LITERAL (RTYPE (tree)))
3102 ast *litTree = searchLitOp (tree, &parent, "*");
3106 ast *tTree = litTree->left;
3107 litTree->left = tree->right;
3108 tree->right = tTree;
3109 /* both operands in litTree are literal now */
3110 decorateType (parent, resultType);
3114 LRVAL (tree) = RRVAL (tree) = 1;
3115 tree->left = addCast (tree->left, resultType, FALSE);
3116 tree->right = addCast (tree->right, resultType, FALSE);
3117 TETYPE (tree) = getSpec (TTYPE (tree) =
3118 computeType (LTYPE (tree),
3125 /*------------------------------------------------------------------*/
3126 /*----------------------------*/
3127 /* unary '+' operator */
3128 /*----------------------------*/
3133 if (!IS_ARITHMETIC (LTYPE (tree)))
3135 werror (E_UNARY_OP, '+');
3136 goto errorTreeReturn;
3139 /* if left is a literal then do it */
3140 if (IS_LITERAL (LTYPE (tree)))
3142 tree->type = EX_VALUE;
3143 tree->opval.val = valFromType (LETYPE (tree));
3145 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3149 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3153 /*------------------------------------------------------------------*/
3154 /*----------------------------*/
3156 /*----------------------------*/
3158 /* this is not a unary operation */
3159 /* if both pointers then problem */
3160 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3161 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3163 werror (E_PTR_PLUS_PTR);
3164 goto errorTreeReturn;
3167 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3168 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3170 werror (E_PLUS_INVALID, "+");
3171 goto errorTreeReturn;
3174 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3175 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3177 werror (E_PLUS_INVALID, "+");
3178 goto errorTreeReturn;
3180 /* if they are both literal then */
3181 /* rewrite the tree */
3182 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3184 tree->type = EX_VALUE;
3185 tree->left = addCast (tree->left, resultType, TRUE);
3186 tree->right = addCast (tree->right, resultType, TRUE);
3187 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3188 valFromType (RETYPE (tree)));
3189 tree->right = tree->left = NULL;
3190 TETYPE (tree) = getSpec (TTYPE (tree) =
3191 tree->opval.val->type);
3195 /* if the right is a pointer or left is a literal
3196 xchange left & right */
3197 if (IS_ARRAY (RTYPE (tree)) ||
3198 IS_PTR (RTYPE (tree)) ||
3199 IS_LITERAL (LTYPE (tree)))
3201 ast *tTree = tree->left;
3202 tree->left = tree->right;
3203 tree->right = tTree;
3206 /* if right is a literal and */
3207 /* left is also an addition/subtraction with a literal then */
3208 /* rearrange the tree */
3209 if (IS_LITERAL (RTYPE (tree)))
3211 ast *litTree, *parent;
3212 litTree = searchLitOp (tree, &parent, "+-");
3215 if (litTree->opval.op == '+')
3219 ast *tTree = litTree->left;
3220 litTree->left = tree->right;
3221 tree->right = tree->left;
3224 else if (litTree->opval.op == '-')
3226 if (IS_LITERAL (RTYPE (litTree)))
3230 ast *tTree = litTree->left;
3231 litTree->left = tree->right;
3232 tree->right = tTree;
3238 ast *tTree = litTree->right;
3239 litTree->right = tree->right;
3240 tree->right = tTree;
3241 litTree->opval.op = '+';
3242 tree->opval.op = '-';
3245 decorateType (parent, resultType);
3249 LRVAL (tree) = RRVAL (tree) = 1;
3250 /* if the left is a pointer */
3251 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3252 TETYPE (tree) = getSpec (TTYPE (tree) =
3256 tree->left = addCast (tree->left, resultType, TRUE);
3257 tree->right = addCast (tree->right, resultType, TRUE);
3258 TETYPE (tree) = getSpec (TTYPE (tree) =
3259 computeType (LTYPE (tree),
3267 /*------------------------------------------------------------------*/
3268 /*----------------------------*/
3270 /*----------------------------*/
3271 case '-': /* can be unary */
3272 /* if right is null then unary */
3276 if (!IS_ARITHMETIC (LTYPE (tree)))
3278 werror (E_UNARY_OP, tree->opval.op);
3279 goto errorTreeReturn;
3282 /* if left is a literal then do it */
3283 if (IS_LITERAL (LTYPE (tree)))
3285 tree->type = EX_VALUE;
3286 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3288 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3289 SPEC_USIGN(TETYPE(tree)) = 0;
3293 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3297 /*------------------------------------------------------------------*/
3298 /*----------------------------*/
3300 /*----------------------------*/
3302 if (!(IS_PTR (LTYPE (tree)) ||
3303 IS_ARRAY (LTYPE (tree)) ||
3304 IS_ARITHMETIC (LTYPE (tree))))
3306 werror (E_PLUS_INVALID, "-");
3307 goto errorTreeReturn;
3310 if (!(IS_PTR (RTYPE (tree)) ||
3311 IS_ARRAY (RTYPE (tree)) ||
3312 IS_ARITHMETIC (RTYPE (tree))))
3314 werror (E_PLUS_INVALID, "-");
3315 goto errorTreeReturn;
3318 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3319 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3320 IS_INTEGRAL (RTYPE (tree))))
3322 werror (E_PLUS_INVALID, "-");
3323 goto errorTreeReturn;
3326 /* if they are both literal then */
3327 /* rewrite the tree */
3328 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3330 tree->type = EX_VALUE;
3331 tree->left = addCast (tree->left, resultType, TRUE);
3332 tree->right = addCast (tree->right, resultType, TRUE);
3333 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3334 valFromType (RETYPE (tree)));
3335 tree->right = tree->left = NULL;
3336 TETYPE (tree) = getSpec (TTYPE (tree) =
3337 tree->opval.val->type);
3341 /* if the left & right are equal then zero */
3342 if (isAstEqual (tree->left, tree->right))
3344 tree->type = EX_VALUE;
3345 tree->left = tree->right = NULL;
3346 tree->opval.val = constVal ("0");
3347 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3351 /* if both of them are pointers or arrays then */
3352 /* the result is going to be an integer */
3353 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3354 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3355 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3357 /* if only the left is a pointer */
3358 /* then result is a pointer */
3359 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3360 TETYPE (tree) = getSpec (TTYPE (tree) =
3364 tree->left = addCast (tree->left, resultType, TRUE);
3365 tree->right = addCast (tree->right, resultType, TRUE);
3367 TETYPE (tree) = getSpec (TTYPE (tree) =
3368 computeType (LTYPE (tree),
3374 LRVAL (tree) = RRVAL (tree) = 1;
3376 /* if right is a literal and */
3377 /* left is also an addition/subtraction with a literal then */
3378 /* rearrange the tree */
3379 if (IS_LITERAL (RTYPE (tree))
3380 /* avoid infinite loop */
3381 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3383 ast *litTree, *litParent;
3384 litTree = searchLitOp (tree, &litParent, "+-");
3387 if (litTree->opval.op == '+')
3391 ast *tTree = litTree->left;
3392 litTree->left = litTree->right;
3393 litTree->right = tree->right;
3394 tree->right = tTree;
3395 tree->opval.op = '+';
3396 litTree->opval.op = '-';
3398 else if (litTree->opval.op == '-')
3400 if (IS_LITERAL (RTYPE (litTree)))
3404 ast *tTree = litTree->left;
3405 litTree->left = tree->right;
3406 tree->right = litParent->left;
3407 litParent->left = tTree;
3408 litTree->opval.op = '+';
3410 tree->decorated = 0;
3411 decorateType (tree, resultType);
3417 ast *tTree = litTree->right;
3418 litTree->right = tree->right;
3419 tree->right = tTree;
3422 decorateType (litParent, resultType);
3427 /*------------------------------------------------------------------*/
3428 /*----------------------------*/
3430 /*----------------------------*/
3432 /* can be only integral type */
3433 if (!IS_INTEGRAL (LTYPE (tree)))
3435 werror (E_UNARY_OP, tree->opval.op);
3436 goto errorTreeReturn;
3439 /* if left is a literal then do it */
3440 if (IS_LITERAL (LTYPE (tree)))
3442 tree->type = EX_VALUE;
3443 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3445 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3446 return addCast (tree, resultType, TRUE);
3449 if (resultType == RESULT_TYPE_BIT &&
3450 IS_UNSIGNED (tree->left->etype) &&
3451 getSize (tree->left->etype) < INTSIZE)
3453 /* promotion rules are responsible for this strange result:
3454 bit -> int -> ~int -> bit
3455 uchar -> int -> ~int -> bit
3457 werror(W_COMPLEMENT);
3459 /* optimize bit-result, even if we optimize a buggy source */
3460 tree->type = EX_VALUE;
3461 tree->opval.val = constVal ("1");
3464 tree->left = addCast (tree->left, resultType, TRUE);
3466 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3469 /*------------------------------------------------------------------*/
3470 /*----------------------------*/
3472 /*----------------------------*/
3474 /* can be pointer */
3475 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3476 !IS_PTR (LTYPE (tree)) &&
3477 !IS_ARRAY (LTYPE (tree)))
3479 werror (E_UNARY_OP, tree->opval.op);
3480 goto errorTreeReturn;
3483 /* if left is a literal then do it */
3484 if (IS_LITERAL (LTYPE (tree)))
3486 tree->type = EX_VALUE;
3487 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3489 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3493 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3496 /*------------------------------------------------------------------*/
3497 /*----------------------------*/
3499 /*----------------------------*/
3503 TTYPE (tree) = LTYPE (tree);
3504 TETYPE (tree) = LETYPE (tree);
3509 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3513 TTYPE (tree) = TETYPE (tree) = newCharLink();
3517 TTYPE (tree) = TETYPE (tree) = newIntLink();
3522 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3524 werror (E_SHIFT_OP_INVALID);
3525 werror (W_CONTINUE, "left & right types are ");
3526 printTypeChain (LTYPE (tree), stderr);
3527 fprintf (stderr, ",");
3528 printTypeChain (RTYPE (tree), stderr);
3529 fprintf (stderr, "\n");
3530 goto errorTreeReturn;
3533 /* make smaller type only if it's a LEFT_OP */
3534 if (tree->opval.op == LEFT_OP)
3535 tree->left = addCast (tree->left, resultType, TRUE);
3537 /* if they are both literal then */
3538 /* rewrite the tree */
3539 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3541 tree->type = EX_VALUE;
3542 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3543 valFromType (RETYPE (tree)),
3544 (tree->opval.op == LEFT_OP ? 1 : 0));
3545 tree->right = tree->left = NULL;
3546 TETYPE (tree) = getSpec (TTYPE (tree) =
3547 tree->opval.val->type);
3551 /* see if this is a GETBYTE operation if yes
3554 ast *otree = optimizeGetByte (tree, resultType);
3557 return decorateType (otree, RESULT_TYPE_NONE);
3560 /* see if this is a GETWORD operation if yes
3563 ast *otree = optimizeGetWord (tree, resultType);
3566 return decorateType (otree, RESULT_TYPE_NONE);
3569 LRVAL (tree) = RRVAL (tree) = 1;
3570 if (tree->opval.op == LEFT_OP)
3572 TETYPE (tree) = getSpec (TTYPE (tree) =
3573 computeType (LTYPE (tree),
3580 /* no promotion necessary */
3581 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3582 if (IS_LITERAL (TTYPE (tree)))
3583 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3586 /* if only the right side is a literal & we are
3587 shifting more than size of the left operand then zero */
3588 if (IS_LITERAL (RTYPE (tree)) &&
3589 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3590 (getSize (TETYPE (tree)) * 8))
3592 if (tree->opval.op==LEFT_OP ||
3593 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3595 lineno=tree->lineno;
3596 werror (W_SHIFT_CHANGED,
3597 (tree->opval.op == LEFT_OP ? "left" : "right"));
3598 tree->type = EX_VALUE;
3599 tree->left = tree->right = NULL;
3600 tree->opval.val = constVal ("0");
3601 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3608 /*------------------------------------------------------------------*/
3609 /*----------------------------*/
3611 /*----------------------------*/
3612 case CAST: /* change the type */
3613 /* cannot cast to an aggregate type */
3614 if (IS_AGGREGATE (LTYPE (tree)))
3616 werror (E_CAST_ILLEGAL);
3617 goto errorTreeReturn;
3620 /* make sure the type is complete and sane */
3621 changePointer(LTYPE(tree));
3622 checkTypeSanity(LETYPE(tree), "(cast)");
3624 /* If code memory is read only, then pointers to code memory */
3625 /* implicitly point to constants -- make this explicit */
3627 sym_link *t = LTYPE(tree);
3628 while (t && t->next)
3630 if (IS_CODEPTR(t) && port->mem.code_ro)
3632 if (IS_SPEC(t->next))
3633 SPEC_CONST (t->next) = 1;
3635 DCL_PTR_CONST (t->next) = 1;
3642 /* if the right is a literal replace the tree */
3643 if (IS_LITERAL (RETYPE (tree))) {
3644 if (!IS_PTR (LTYPE (tree))) {
3645 tree->type = EX_VALUE;
3647 valCastLiteral (LTYPE (tree),
3648 floatFromVal (valFromType (RETYPE (tree))));
3651 TTYPE (tree) = tree->opval.val->type;
3652 tree->values.literalFromCast = 1;
3653 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3654 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3655 sym_link *rest = LTYPE(tree)->next;
3656 werror(W_LITERAL_GENERIC);
3657 TTYPE(tree) = newLink(DECLARATOR);
3658 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3659 TTYPE(tree)->next = rest;
3660 tree->left->opval.lnk = TTYPE(tree);
3663 TTYPE (tree) = LTYPE (tree);
3667 TTYPE (tree) = LTYPE (tree);
3671 #if 0 // this is already checked, now this could be explicit
3672 /* if pointer to struct then check names */
3673 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3674 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3675 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3677 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3678 SPEC_STRUCT(LETYPE(tree))->tag);
3681 if (IS_ADDRESS_OF_OP(tree->right)
3682 && IS_AST_SYM_VALUE (tree->right->left)
3683 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3685 symbol * sym = AST_SYMBOL (tree->right->left);
3686 unsigned int gptype = 0;
3687 unsigned int addr = SPEC_ADDR (sym->etype);
3689 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3691 switch (SPEC_SCLS (sym->etype))
3694 gptype = GPTYPE_CODE;
3697 gptype = GPTYPE_FAR;
3701 gptype = GPTYPE_NEAR;
3704 gptype = GPTYPE_XSTACK;
3709 addr |= gptype << (8*(GPTRSIZE - 1));
3712 tree->type = EX_VALUE;
3714 valCastLiteral (LTYPE (tree), addr);
3715 TTYPE (tree) = tree->opval.val->type;
3716 TETYPE (tree) = getSpec (TTYPE (tree));
3719 tree->values.literalFromCast = 1;
3723 /* handle offsetof macro: */
3724 /* #define offsetof(TYPE, MEMBER) \ */
3725 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3726 if (IS_ADDRESS_OF_OP(tree->right)
3727 && IS_AST_OP (tree->right->left)
3728 && tree->right->left->opval.op == PTR_OP
3729 && IS_AST_OP (tree->right->left->left)
3730 && tree->right->left->left->opval.op == CAST
3731 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3733 symbol *element = getStructElement (
3734 SPEC_STRUCT (LETYPE(tree->right->left)),
3735 AST_SYMBOL(tree->right->left->right)
3739 tree->type = EX_VALUE;
3740 tree->opval.val = valCastLiteral (
3743 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3746 TTYPE (tree) = tree->opval.val->type;
3747 TETYPE (tree) = getSpec (TTYPE (tree));
3754 /* if the right is a literal replace the tree */
3755 if (IS_LITERAL (RETYPE (tree))) {
3757 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3758 /* rewrite (type *)litaddr
3760 and define type at litaddr temp
3761 (but only if type's storage class is not generic)
3763 ast *newTree = newNode ('&', NULL, NULL);
3766 TTYPE (newTree) = LTYPE (tree);
3767 TETYPE (newTree) = getSpec(LTYPE (tree));
3769 /* define a global symbol at the casted address*/
3770 sym = newSymbol(genSymName (0), 0);
3771 sym->type = LTYPE (tree)->next;
3773 sym->type = newLink (V_VOID);
3774 sym->etype = getSpec(sym->type);
3775 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3776 sym->lineDef = tree->lineno;
3779 SPEC_STAT (sym->etype) = 1;
3780 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3781 SPEC_ABSA(sym->etype) = 1;
3782 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3785 newTree->left = newAst_VALUE(symbolVal(sym));
3786 newTree->left->lineno = tree->lineno;
3787 LTYPE (newTree) = sym->type;
3788 LETYPE (newTree) = sym->etype;
3789 LLVAL (newTree) = 1;
3790 LRVAL (newTree) = 0;
3791 TLVAL (newTree) = 1;
3795 if (!IS_PTR (LTYPE (tree))) {
3796 tree->type = EX_VALUE;
3798 valCastLiteral (LTYPE (tree),
3799 floatFromVal (valFromType (RTYPE (tree))));
3800 TTYPE (tree) = tree->opval.val->type;
3803 tree->values.literalFromCast = 1;
3804 TETYPE (tree) = getSpec (TTYPE (tree));
3808 TTYPE (tree) = LTYPE (tree);
3812 TETYPE (tree) = getSpec (TTYPE (tree));
3816 /*------------------------------------------------------------------*/
3817 /*----------------------------*/
3818 /* logical &&, || */
3819 /*----------------------------*/
3822 /* each must be arithmetic type or be a pointer */
3823 if (!IS_PTR (LTYPE (tree)) &&
3824 !IS_ARRAY (LTYPE (tree)) &&
3825 !IS_INTEGRAL (LTYPE (tree)))
3827 werror (E_COMPARE_OP);
3828 goto errorTreeReturn;
3831 if (!IS_PTR (RTYPE (tree)) &&
3832 !IS_ARRAY (RTYPE (tree)) &&
3833 !IS_INTEGRAL (RTYPE (tree)))
3835 werror (E_COMPARE_OP);
3836 goto errorTreeReturn;
3838 /* if they are both literal then */
3839 /* rewrite the tree */
3840 if (IS_LITERAL (RTYPE (tree)) &&
3841 IS_LITERAL (LTYPE (tree)))
3843 tree->type = EX_VALUE;
3844 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3845 valFromType (RTYPE (tree)),
3847 tree->right = tree->left = NULL;
3848 TETYPE (tree) = getSpec (TTYPE (tree) =
3849 tree->opval.val->type);
3852 LRVAL (tree) = RRVAL (tree) = 1;
3853 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3856 /*------------------------------------------------------------------*/
3857 /*----------------------------*/
3858 /* comparison operators */
3859 /*----------------------------*/
3867 ast *lt = optimizeCompare (tree);
3873 /* if they are pointers they must be castable */
3874 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3876 if (tree->opval.op==EQ_OP &&
3877 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3878 // we cannot cast a gptr to a !gptr: switch the leaves
3879 struct ast *s=tree->left;
3880 tree->left=tree->right;
3883 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3885 werror (E_COMPARE_OP);
3886 fprintf (stderr, "comparing type ");
3887 printTypeChain (LTYPE (tree), stderr);
3888 fprintf (stderr, "to type ");
3889 printTypeChain (RTYPE (tree), stderr);
3890 fprintf (stderr, "\n");
3891 goto errorTreeReturn;
3894 /* else they should be promotable to one another */
3897 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3898 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3900 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3902 werror (E_COMPARE_OP);
3903 fprintf (stderr, "comparing type ");
3904 printTypeChain (LTYPE (tree), stderr);
3905 fprintf (stderr, "to type ");
3906 printTypeChain (RTYPE (tree), stderr);
3907 fprintf (stderr, "\n");
3908 goto errorTreeReturn;
3911 /* if unsigned value < 0 then always false */
3912 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3913 if (SPEC_USIGN(LETYPE(tree)) &&
3914 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3915 IS_LITERAL(RTYPE(tree)) &&
3916 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3918 if (tree->opval.op == '<')
3922 if (tree->opval.op == '>')
3924 if (resultType == RESULT_TYPE_IFX)
3926 /* the parent is an ifx: */
3927 /* if (unsigned value) */
3931 /* (unsigned value) ? 1 : 0 */
3932 tree->opval.op = '?';
3933 tree->right = newNode (':',
3934 newAst_VALUE (constVal ("1")),
3935 tree->right); /* val 0 */
3936 tree->right->lineno = tree->lineno;
3937 tree->right->left->lineno = tree->lineno;
3938 decorateType (tree->right, RESULT_TYPE_NONE);
3941 /* if they are both literal then */
3942 /* rewrite the tree */
3943 if (IS_LITERAL (RTYPE (tree)) &&
3944 IS_LITERAL (LTYPE (tree)))
3946 tree->type = EX_VALUE;
3947 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3948 valFromType (RETYPE (tree)),
3950 tree->right = tree->left = NULL;
3951 TETYPE (tree) = getSpec (TTYPE (tree) =
3952 tree->opval.val->type);
3955 /* if one is 'signed char ' and the other one is 'unsigned char' */
3956 /* it's necessary to promote to int */
3957 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
3958 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
3960 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
3961 if it's possible to use a 'signed char' */
3963 /* is left a 'unsigned char'? */
3964 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
3965 /* the value range of a 'unsigned char' is 0...255;
3966 if the actual value is < 128 it can be changed to signed */
3967 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
3969 /* now we've got 2 'signed char'! */
3970 SPEC_USIGN (RETYPE (tree)) = 0;
3972 /* same test for the left operand: */
3973 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
3974 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
3976 SPEC_USIGN (LETYPE (tree)) = 0;
3980 werror (W_CMP_SU_CHAR);
3981 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
3982 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
3986 LRVAL (tree) = RRVAL (tree) = 1;
3987 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3990 /*------------------------------------------------------------------*/
3991 /*----------------------------*/
3993 /*----------------------------*/
3994 case SIZEOF: /* evaluate wihout code generation */
3995 /* change the type to a integer */
3997 int size = getSize (tree->right->ftype);
3998 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3999 if (!size && !IS_VOID(tree->right->ftype))
4000 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4002 tree->type = EX_VALUE;
4003 tree->opval.val = constVal (buffer);
4004 tree->right = tree->left = NULL;
4005 TETYPE (tree) = getSpec (TTYPE (tree) =
4006 tree->opval.val->type);
4009 /*------------------------------------------------------------------*/
4010 /*----------------------------*/
4012 /*----------------------------*/
4014 /* return typeof enum value */
4015 tree->type = EX_VALUE;
4018 if (IS_SPEC(tree->right->ftype)) {
4019 switch (SPEC_NOUN(tree->right->ftype)) {
4021 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4022 else typeofv = TYPEOF_INT;
4025 typeofv = TYPEOF_FLOAT;
4028 typeofv = TYPEOF_FIXED16X16;
4031 typeofv = TYPEOF_CHAR;
4034 typeofv = TYPEOF_VOID;
4037 typeofv = TYPEOF_STRUCT;
4040 typeofv = TYPEOF_BITFIELD;
4043 typeofv = TYPEOF_BIT;
4046 typeofv = TYPEOF_SBIT;
4052 switch (DCL_TYPE(tree->right->ftype)) {
4054 typeofv = TYPEOF_POINTER;
4057 typeofv = TYPEOF_FPOINTER;
4060 typeofv = TYPEOF_CPOINTER;
4063 typeofv = TYPEOF_GPOINTER;
4066 typeofv = TYPEOF_PPOINTER;
4069 typeofv = TYPEOF_IPOINTER;
4072 typeofv = TYPEOF_ARRAY;
4075 typeofv = TYPEOF_FUNCTION;
4081 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4082 tree->opval.val = constVal (buffer);
4083 tree->right = tree->left = NULL;
4084 TETYPE (tree) = getSpec (TTYPE (tree) =
4085 tree->opval.val->type);
4088 /*------------------------------------------------------------------*/
4089 /*----------------------------*/
4090 /* conditional operator '?' */
4091 /*----------------------------*/
4093 /* the type is value of the colon operator (on the right) */
4094 assert (IS_COLON_OP (tree->right));
4095 /* if already known then replace the tree : optimizer will do it
4096 but faster to do it here */
4097 if (IS_LITERAL (LTYPE (tree)))
4099 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4100 return decorateType (tree->right->left, resultTypeProp);
4102 return decorateType (tree->right->right, resultTypeProp);
4106 tree->right = decorateType (tree->right, resultTypeProp);
4107 TTYPE (tree) = RTYPE (tree);
4108 TETYPE (tree) = getSpec (TTYPE (tree));
4113 /* if they don't match we have a problem */
4114 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4115 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4117 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4118 goto errorTreeReturn;
4121 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4122 resultType, tree->opval.op);
4123 TETYPE (tree) = getSpec (TTYPE (tree));
4127 #if 0 // assignment operators are converted by the parser
4128 /*------------------------------------------------------------------*/
4129 /*----------------------------*/
4130 /* assignment operators */
4131 /*----------------------------*/
4134 /* for these it must be both must be integral */
4135 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4136 !IS_ARITHMETIC (RTYPE (tree)))
4138 werror (E_OPS_INTEGRAL);
4139 goto errorTreeReturn;
4142 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4144 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4145 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4149 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4150 goto errorTreeReturn;
4161 /* for these it must be both must be integral */
4162 if (!IS_INTEGRAL (LTYPE (tree)) ||
4163 !IS_INTEGRAL (RTYPE (tree)))
4165 werror (E_OPS_INTEGRAL);
4166 goto errorTreeReturn;
4169 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4171 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4172 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4176 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4177 goto errorTreeReturn;
4183 /*------------------------------------------------------------------*/
4184 /*----------------------------*/
4186 /*----------------------------*/
4188 if (!(IS_PTR (LTYPE (tree)) ||
4189 IS_ARITHMETIC (LTYPE (tree))))
4191 werror (E_PLUS_INVALID, "-=");
4192 goto errorTreeReturn;
4195 if (!(IS_PTR (RTYPE (tree)) ||
4196 IS_ARITHMETIC (RTYPE (tree))))
4198 werror (E_PLUS_INVALID, "-=");
4199 goto errorTreeReturn;
4202 TETYPE (tree) = getSpec (TTYPE (tree) =
4203 computeType (LTYPE (tree),
4208 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4209 werror (E_CODE_WRITE, "-=");
4213 werror (E_LVALUE_REQUIRED, "-=");
4214 goto errorTreeReturn;
4220 /*------------------------------------------------------------------*/
4221 /*----------------------------*/
4223 /*----------------------------*/
4225 /* this is not a unary operation */
4226 /* if both pointers then problem */
4227 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4229 werror (E_PTR_PLUS_PTR);
4230 goto errorTreeReturn;
4233 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4235 werror (E_PLUS_INVALID, "+=");
4236 goto errorTreeReturn;
4239 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4241 werror (E_PLUS_INVALID, "+=");
4242 goto errorTreeReturn;
4245 TETYPE (tree) = getSpec (TTYPE (tree) =
4246 computeType (LTYPE (tree),
4251 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4252 werror (E_CODE_WRITE, "+=");
4256 werror (E_LVALUE_REQUIRED, "+=");
4257 goto errorTreeReturn;
4260 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4261 tree->opval.op = '=';
4266 /*------------------------------------------------------------------*/
4267 /*----------------------------*/
4268 /* straight assignemnt */
4269 /*----------------------------*/
4271 /* cannot be an aggregate */
4272 if (IS_AGGREGATE (LTYPE (tree)))
4274 werror (E_AGGR_ASSIGN);
4275 goto errorTreeReturn;
4278 /* they should either match or be castable */
4279 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4281 werror (E_TYPE_MISMATCH, "assignment", " ");
4282 printFromToType(RTYPE(tree),LTYPE(tree));
4285 /* if the left side of the tree is of type void
4286 then report error */
4287 if (IS_VOID (LTYPE (tree)))
4289 werror (E_CAST_ZERO);
4290 printFromToType(RTYPE(tree), LTYPE(tree));
4293 TETYPE (tree) = getSpec (TTYPE (tree) =
4297 if (!tree->initMode ) {
4298 if (IS_CONSTANT(LTYPE(tree)))
4299 werror (E_CODE_WRITE, "=");
4303 werror (E_LVALUE_REQUIRED, "=");
4304 goto errorTreeReturn;
4309 /*------------------------------------------------------------------*/
4310 /*----------------------------*/
4311 /* comma operator */
4312 /*----------------------------*/
4314 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4317 /*------------------------------------------------------------------*/
4318 /*----------------------------*/
4320 /*----------------------------*/
4323 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4324 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4326 if (tree->left->opval.op == '*' && !tree->left->right)
4327 tree->left = tree->left->left;
4330 /* require a function or pointer to function */
4331 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4333 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4334 goto errorTreeReturn;
4337 /* if there are parms, make sure that
4338 parms are decorate / process / reverse only once */
4340 !tree->right->decorated)
4345 if (IS_FUNCPTR (LTYPE (tree)))
4346 functype = LTYPE (tree)->next;
4348 functype = LTYPE (tree);
4350 if (processParms (tree->left, FUNC_ARGS(functype),
4351 &tree->right, &parmNumber, TRUE))
4353 goto errorTreeReturn;
4356 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4357 !IFFUNC_ISBUILTIN(functype))
4359 reverseParms (tree->right);
4362 TTYPE (tree) = functype->next;
4363 TETYPE (tree) = getSpec (TTYPE (tree));
4367 /*------------------------------------------------------------------*/
4368 /*----------------------------*/
4369 /* return statement */
4370 /*----------------------------*/
4375 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4377 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4378 printFromToType (RTYPE(tree), currFunc->type->next);
4379 goto errorTreeReturn;
4382 if (IS_VOID (currFunc->type->next)
4384 !IS_VOID (RTYPE (tree)))
4386 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4387 goto errorTreeReturn;
4390 /* if there is going to be a casting required then add it */
4391 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4394 decorateType (newNode (CAST,
4395 newAst_LINK (copyLinkChain (currFunc->type->next)),
4405 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4407 werror (W_VOID_FUNC, currFunc->name);
4408 goto errorTreeReturn;
4411 TTYPE (tree) = TETYPE (tree) = NULL;
4414 /*------------------------------------------------------------------*/
4415 /*----------------------------*/
4416 /* switch statement */
4417 /*----------------------------*/
4419 /* the switch value must be an integer */
4420 if (!IS_INTEGRAL (LTYPE (tree)))
4422 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4423 goto errorTreeReturn;
4426 TTYPE (tree) = TETYPE (tree) = NULL;
4429 /*------------------------------------------------------------------*/
4430 /*----------------------------*/
4432 /*----------------------------*/
4434 tree->left = backPatchLabels (tree->left,
4437 TTYPE (tree) = TETYPE (tree) = NULL;
4440 /*------------------------------------------------------------------*/
4441 /*----------------------------*/
4443 /*----------------------------*/
4446 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4447 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4448 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4450 /* if the for loop is reversible then
4451 reverse it otherwise do what we normally
4457 if (isLoopReversible (tree, &sym, &init, &end))
4458 return reverseLoop (tree, sym, init, end);
4460 return decorateType (createFor (AST_FOR (tree, trueLabel),
4461 AST_FOR (tree, continueLabel),
4462 AST_FOR (tree, falseLabel),
4463 AST_FOR (tree, condLabel),
4464 AST_FOR (tree, initExpr),
4465 AST_FOR (tree, condExpr),
4466 AST_FOR (tree, loopExpr),
4467 tree->left), RESULT_TYPE_NONE);
4470 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4471 "node PARAM shouldn't be processed here");
4472 /* but in processParams() */
4475 TTYPE (tree) = TETYPE (tree) = NULL;
4479 /* some error found this tree will be killed */
4481 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4482 tree->opval.op = NULLOP;
4488 /*-----------------------------------------------------------------*/
4489 /* sizeofOp - processes size of operation */
4490 /*-----------------------------------------------------------------*/
4492 sizeofOp (sym_link * type)
4497 /* make sure the type is complete and sane */
4498 checkTypeSanity(type, "(sizeof)");
4500 /* get the size and convert it to character */
4501 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4502 if (!size && !IS_VOID(type))
4503 werror (E_SIZEOF_INCOMPLETE_TYPE);
4505 /* now convert into value */
4506 return constVal (buff);
4510 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4511 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4512 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4513 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4514 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4515 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4516 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4518 /*-----------------------------------------------------------------*/
4519 /* backPatchLabels - change and or not operators to flow control */
4520 /*-----------------------------------------------------------------*/
4522 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4528 if (!(IS_ANDORNOT (tree)))
4531 /* if this an and */
4534 static int localLbl = 0;
4537 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4538 localLabel = newSymbol (buffer, NestLevel);
4540 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4542 /* if left is already a IFX then just change the if true label in that */
4543 if (!IS_IFX (tree->left))
4544 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4546 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4547 /* right is a IFX then just join */
4548 if (IS_IFX (tree->right))
4549 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4551 tree->right = createLabel (localLabel, tree->right);
4552 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4554 return newNode (NULLOP, tree->left, tree->right);
4557 /* if this is an or operation */
4560 static int localLbl = 0;
4563 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4564 localLabel = newSymbol (buffer, NestLevel);
4566 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4568 /* if left is already a IFX then just change the if true label in that */
4569 if (!IS_IFX (tree->left))
4570 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4572 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4573 /* right is a IFX then just join */
4574 if (IS_IFX (tree->right))
4575 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4577 tree->right = createLabel (localLabel, tree->right);
4578 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4580 return newNode (NULLOP, tree->left, tree->right);
4586 int wasnot = IS_NOT (tree->left);
4587 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4589 /* if the left is already a IFX */
4590 if (!IS_IFX (tree->left))
4591 tree->left = newNode (IFX, tree->left, NULL);
4595 tree->left->trueLabel = trueLabel;
4596 tree->left->falseLabel = falseLabel;
4600 tree->left->trueLabel = falseLabel;
4601 tree->left->falseLabel = trueLabel;
4608 tree->trueLabel = trueLabel;
4609 tree->falseLabel = falseLabel;
4616 /*-----------------------------------------------------------------*/
4617 /* createBlock - create expression tree for block */
4618 /*-----------------------------------------------------------------*/
4620 createBlock (symbol * decl, ast * body)
4624 /* if the block has nothing */
4628 ex = newNode (BLOCK, NULL, body);
4629 ex->values.sym = decl;
4636 /*-----------------------------------------------------------------*/
4637 /* createLabel - creates the expression tree for labels */
4638 /*-----------------------------------------------------------------*/
4640 createLabel (symbol * label, ast * stmnt)
4643 char name[SDCC_NAME_MAX + 1];
4646 /* must create fresh symbol if the symbol name */
4647 /* exists in the symbol table, since there can */
4648 /* be a variable with the same name as the labl */
4649 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4650 (csym->level == label->level))
4651 label = newSymbol (label->name, label->level);
4653 /* change the name before putting it in add _ */
4654 SNPRINTF(name, sizeof(name), "%s", label->name);
4656 /* put the label in the LabelSymbol table */
4657 /* but first check if a label of the same */
4659 if ((csym = findSym (LabelTab, NULL, name)))
4660 werror (E_DUPLICATE_LABEL, label->name);
4662 addSym (LabelTab, label, name, label->level, 0, 0);
4666 label->key = labelKey++;
4667 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4673 /*-----------------------------------------------------------------*/
4674 /* createCase - generates the parsetree for a case statement */
4675 /*-----------------------------------------------------------------*/
4677 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4679 char caseLbl[SDCC_NAME_MAX + 1];
4683 /* if the switch statement does not exist */
4684 /* then case is out of context */
4687 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4691 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4692 /* if not a constant then error */
4693 if (!IS_LITERAL (caseVal->ftype))
4695 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4699 /* if not a integer than error */
4700 if (!IS_INTEGRAL (caseVal->ftype))
4702 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4706 /* find the end of the switch values chain */
4707 if (!(val = swStat->values.switchVals.swVals))
4708 swStat->values.switchVals.swVals = caseVal->opval.val;
4711 /* also order the cases according to value */
4713 int cVal = (int) floatFromVal (caseVal->opval.val);
4714 while (val && (int) floatFromVal (val) < cVal)
4720 /* if we reached the end then */
4723 pval->next = caseVal->opval.val;
4725 else if ((int) floatFromVal (val) == cVal)
4727 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4733 /* we found a value greater than */
4734 /* the current value we must add this */
4735 /* before the value */
4736 caseVal->opval.val->next = val;
4738 /* if this was the first in chain */
4739 if (swStat->values.switchVals.swVals == val)
4740 swStat->values.switchVals.swVals =
4743 pval->next = caseVal->opval.val;
4748 /* create the case label */
4749 SNPRINTF(caseLbl, sizeof(caseLbl),
4751 swStat->values.switchVals.swNum,
4752 (int) floatFromVal (caseVal->opval.val));
4754 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4759 /*-----------------------------------------------------------------*/
4760 /* createDefault - creates the parse tree for the default statement */
4761 /*-----------------------------------------------------------------*/
4763 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4765 char defLbl[SDCC_NAME_MAX + 1];
4767 /* if the switch statement does not exist */
4768 /* then case is out of context */
4771 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4775 if (swStat->values.switchVals.swDefault)
4777 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4782 /* turn on the default flag */
4783 swStat->values.switchVals.swDefault = 1;
4785 /* create the label */
4786 SNPRINTF (defLbl, sizeof(defLbl),
4787 "_default_%d", swStat->values.switchVals.swNum);
4788 return createLabel (newSymbol (defLbl, 0), stmnt);
4791 /*-----------------------------------------------------------------*/
4792 /* createIf - creates the parsetree for the if statement */
4793 /*-----------------------------------------------------------------*/
4795 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4797 static int Lblnum = 0;
4799 symbol *ifTrue, *ifFalse, *ifEnd;
4801 /* if neither exists */
4802 if (!elseBody && !ifBody) {
4803 // if there are no side effects (i++, j() etc)
4804 if (!hasSEFcalls(condAst)) {
4809 /* create the labels */
4810 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4811 ifFalse = newSymbol (buffer, NestLevel);
4812 /* if no else body then end == false */
4817 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4818 ifEnd = newSymbol (buffer, NestLevel);
4821 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4822 ifTrue = newSymbol (buffer, NestLevel);
4826 /* attach the ifTrue label to the top of it body */
4827 ifBody = createLabel (ifTrue, ifBody);
4828 /* attach a goto end to the ifBody if else is present */
4831 ifBody = newNode (NULLOP, ifBody,
4833 newAst_VALUE (symbolVal (ifEnd)),
4835 /* put the elseLabel on the else body */
4836 elseBody = createLabel (ifFalse, elseBody);
4837 /* out the end at the end of the body */
4838 elseBody = newNode (NULLOP,
4840 createLabel (ifEnd, NULL));
4844 ifBody = newNode (NULLOP, ifBody,
4845 createLabel (ifFalse, NULL));
4847 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4848 if (IS_IFX (condAst))
4851 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4853 return newNode (NULLOP, ifTree,
4854 newNode (NULLOP, ifBody, elseBody));
4858 /*-----------------------------------------------------------------*/
4859 /* createDo - creates parse tree for do */
4862 /* _docontinue_n: */
4863 /* condition_expression +-> trueLabel -> _dobody_n */
4865 /* +-> falseLabel-> _dobreak_n */
4867 /*-----------------------------------------------------------------*/
4869 createDo (symbol * trueLabel, symbol * continueLabel,
4870 symbol * falseLabel, ast * condAst, ast * doBody)
4875 /* if the body does not exist then it is simple */
4878 condAst = backPatchLabels (condAst, continueLabel, NULL);
4879 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4880 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4881 doTree->trueLabel = continueLabel;
4882 doTree->falseLabel = NULL;
4886 /* otherwise we have a body */
4887 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4889 /* attach the body label to the top */
4890 doBody = createLabel (trueLabel, doBody);
4891 /* attach the continue label to end of body */
4892 doBody = newNode (NULLOP, doBody,
4893 createLabel (continueLabel, NULL));
4895 /* now put the break label at the end */
4896 if (IS_IFX (condAst))
4899 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4901 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4903 /* putting it together */
4904 return newNode (NULLOP, doBody, doTree);
4907 /*-----------------------------------------------------------------*/
4908 /* createFor - creates parse tree for 'for' statement */
4911 /* condExpr +-> trueLabel -> _forbody_n */
4913 /* +-> falseLabel-> _forbreak_n */
4916 /* _forcontinue_n: */
4918 /* goto _forcond_n ; */
4920 /*-----------------------------------------------------------------*/
4922 createFor (symbol * trueLabel, symbol * continueLabel,
4923 symbol * falseLabel, symbol * condLabel,
4924 ast * initExpr, ast * condExpr, ast * loopExpr,
4929 /* if loopexpression not present then we can generate it */
4930 /* the same way as a while */
4932 return newNode (NULLOP, initExpr,
4933 createWhile (trueLabel, continueLabel,
4934 falseLabel, condExpr, forBody));
4935 /* vanilla for statement */
4936 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4938 if (condExpr && !IS_IFX (condExpr))
4939 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4942 /* attach condition label to condition */
4943 condExpr = createLabel (condLabel, condExpr);
4945 /* attach body label to body */
4946 forBody = createLabel (trueLabel, forBody);
4948 /* attach continue to forLoop expression & attach */
4949 /* goto the forcond @ and of loopExpression */
4950 loopExpr = createLabel (continueLabel,
4954 newAst_VALUE (symbolVal (condLabel)),
4956 /* now start putting them together */
4957 forTree = newNode (NULLOP, initExpr, condExpr);
4958 forTree = newNode (NULLOP, forTree, forBody);
4959 forTree = newNode (NULLOP, forTree, loopExpr);
4960 /* finally add the break label */
4961 forTree = newNode (NULLOP, forTree,
4962 createLabel (falseLabel, NULL));
4966 /*-----------------------------------------------------------------*/
4967 /* createWhile - creates parse tree for while statement */
4968 /* the while statement will be created as follows */
4970 /* _while_continue_n: */
4971 /* condition_expression +-> trueLabel -> _while_boby_n */
4973 /* +-> falseLabel -> _while_break_n */
4974 /* _while_body_n: */
4976 /* goto _while_continue_n */
4977 /* _while_break_n: */
4978 /*-----------------------------------------------------------------*/
4980 createWhile (symbol * trueLabel, symbol * continueLabel,
4981 symbol * falseLabel, ast * condExpr, ast * whileBody)
4985 /* put the continue label */
4986 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4987 condExpr = createLabel (continueLabel, condExpr);
4988 condExpr->lineno = 0;
4990 /* put the body label in front of the body */
4991 whileBody = createLabel (trueLabel, whileBody);
4992 whileBody->lineno = 0;
4993 /* put a jump to continue at the end of the body */
4994 /* and put break label at the end of the body */
4995 whileBody = newNode (NULLOP,
4998 newAst_VALUE (symbolVal (continueLabel)),
4999 createLabel (falseLabel, NULL)));
5001 /* put it all together */
5002 if (IS_IFX (condExpr))
5003 whileTree = condExpr;
5006 whileTree = newNode (IFX, condExpr, NULL);
5007 /* put the true & false labels in place */
5008 whileTree->trueLabel = trueLabel;
5009 whileTree->falseLabel = falseLabel;
5012 return newNode (NULLOP, whileTree, whileBody);
5015 /*-----------------------------------------------------------------*/
5016 /* isShiftRightLitVal _BitAndLitVal - helper function */
5017 /*-----------------------------------------------------------------*/
5019 isShiftRightLitVal_BitAndLitVal (ast * tree)
5021 /* if this is not a bit and */
5022 if (!IS_BITAND (tree))
5025 /* will look for tree of the form
5026 ( expr >> litval2) & litval1 */
5027 if (!IS_AST_LIT_VALUE (tree->right))
5030 if (!IS_RIGHT_OP (tree->left))
5033 if (!IS_AST_LIT_VALUE (tree->left->right))
5036 return tree->left->left;
5039 /*-----------------------------------------------------------------*/
5040 /* isBitAndPowOf2 - helper function */
5041 /*-----------------------------------------------------------------*/
5043 isBitAndPow2 (ast * tree)
5045 /* if this is not a bit and */
5046 if (!IS_BITAND (tree))
5049 /* will look for tree of the form
5050 ( expr & (1 << litval) */
5051 if (!IS_AST_LIT_VALUE (tree->right))
5054 return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5057 /*-----------------------------------------------------------------*/
5058 /* optimizeGetHbit - get highest order bit of the expression */
5059 /*-----------------------------------------------------------------*/
5061 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5066 expr = isShiftRightLitVal_BitAndLitVal(tree);
5069 if ((AST_LIT_VALUE (tree->right) != 1) ||
5070 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5071 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5074 if (!expr && (resultType == RESULT_TYPE_BIT))
5077 if (isBitAndPow2 (tree) != getSize (TTYPE (expr)) * 8 - 1)
5083 /* make sure the port supports GETHBIT */
5084 if (port->hasExtBitOp
5085 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5088 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5091 /*-----------------------------------------------------------------*/
5092 /* optimizeGetAbit - get a single bit of the expression */
5093 /*-----------------------------------------------------------------*/
5095 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5100 expr = isShiftRightLitVal_BitAndLitVal(tree);
5103 if (AST_LIT_VALUE (tree->right) != 1)
5105 count = tree->left->right;
5107 if (!expr && (resultType == RESULT_TYPE_BIT))
5109 int p2 = isBitAndPow2 (tree);
5113 count = newAst_VALUE (valueFromLit (p2));
5119 /* make sure the port supports GETABIT */
5120 if (port->hasExtBitOp
5121 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5124 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5128 /*-----------------------------------------------------------------*/
5129 /* optimizeGetByte - get a byte of the expression */
5130 /*-----------------------------------------------------------------*/
5132 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5138 expr = isShiftRightLitVal_BitAndLitVal(tree);
5141 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5142 count = tree->left->right;
5143 if (AST_LIT_VALUE (tree->right) != 0xFF)
5146 if (!expr && resultType == RESULT_TYPE_CHAR)
5148 /* if this is a right shift over a multiple of 8 */
5149 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5151 i = (unsigned int) AST_LIT_VALUE (tree->right);
5152 count = tree->right;
5156 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5159 /* make sure the port supports GETBYTE */
5160 if (port->hasExtBitOp
5161 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5164 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5167 /*-----------------------------------------------------------------*/
5168 /* optimizeGetWord - get two bytes of the expression */
5169 /*-----------------------------------------------------------------*/
5171 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5177 expr = isShiftRightLitVal_BitAndLitVal(tree);
5180 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5181 count = tree->left->right;
5182 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5185 if (!expr && resultType == RESULT_TYPE_INT)
5187 /* if this is a right shift over a multiple of 8 */
5188 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5190 i = (unsigned int) AST_LIT_VALUE (tree->right);
5191 count = tree->right;
5195 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5198 /* make sure the port supports GETWORD */
5199 if (port->hasExtBitOp
5200 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5203 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5206 /*-----------------------------------------------------------------*/
5207 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5208 /*-----------------------------------------------------------------*/
5210 optimizeRRCRLC (ast * root)
5212 /* will look for trees of the form
5213 (?expr << 1) | (?expr >> 7) or
5214 (?expr >> 7) | (?expr << 1) will make that
5215 into a RLC : operation ..
5217 (?expr >> 1) | (?expr << 7) or
5218 (?expr << 7) | (?expr >> 1) will make that
5219 into a RRC operation
5220 note : by 7 I mean (number of bits required to hold the
5222 /* if the root operations is not a | operation the not */
5223 if (!IS_BITOR (root))
5226 /* I have to think of a better way to match patterns this sucks */
5227 /* that aside let start looking for the first case : I use a the
5228 negative check a lot to improve the efficiency */
5229 /* (?expr << 1) | (?expr >> 7) */
5230 if (IS_LEFT_OP (root->left) &&
5231 IS_RIGHT_OP (root->right))
5234 if (!SPEC_USIGN (TETYPE (root->left->left)))
5237 if (!IS_AST_LIT_VALUE (root->left->right) ||
5238 !IS_AST_LIT_VALUE (root->right->right))
5241 /* make sure it is the same expression */
5242 if (!isAstEqual (root->left->left,
5246 if (AST_LIT_VALUE (root->left->right) != 1)
5249 if (AST_LIT_VALUE (root->right->right) !=
5250 (getSize (TTYPE (root->left->left)) * 8 - 1))
5253 /* make sure the port supports RLC */
5254 if (port->hasExtBitOp
5255 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5258 /* whew got the first case : create the AST */
5259 return newNode (RLC, root->left->left, NULL);
5263 /* check for second case */
5264 /* (?expr >> 7) | (?expr << 1) */
5265 if (IS_LEFT_OP (root->right) &&
5266 IS_RIGHT_OP (root->left))
5269 if (!SPEC_USIGN (TETYPE (root->left->left)))
5272 if (!IS_AST_LIT_VALUE (root->left->right) ||
5273 !IS_AST_LIT_VALUE (root->right->right))
5276 /* make sure it is the same symbol */
5277 if (!isAstEqual (root->left->left,
5281 if (AST_LIT_VALUE (root->right->right) != 1)
5284 if (AST_LIT_VALUE (root->left->right) !=
5285 (getSize (TTYPE (root->left->left)) * 8 - 1))
5288 /* make sure the port supports RLC */
5289 if (port->hasExtBitOp
5290 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5293 /* whew got the first case : create the AST */
5294 return newNode (RLC, root->left->left, NULL);
5299 /* third case for RRC */
5300 /* (?symbol >> 1) | (?symbol << 7) */
5301 if (IS_LEFT_OP (root->right) &&
5302 IS_RIGHT_OP (root->left))
5305 if (!SPEC_USIGN (TETYPE (root->left->left)))
5308 if (!IS_AST_LIT_VALUE (root->left->right) ||
5309 !IS_AST_LIT_VALUE (root->right->right))
5312 /* make sure it is the same symbol */
5313 if (!isAstEqual (root->left->left,
5317 if (AST_LIT_VALUE (root->left->right) != 1)
5320 if (AST_LIT_VALUE (root->right->right) !=
5321 (getSize (TTYPE (root->left->left)) * 8 - 1))
5324 /* make sure the port supports RRC */
5325 if (port->hasExtBitOp
5326 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5329 /* whew got the first case : create the AST */
5330 return newNode (RRC, root->left->left, NULL);
5334 /* fourth and last case for now */
5335 /* (?symbol << 7) | (?symbol >> 1) */
5336 if (IS_RIGHT_OP (root->right) &&
5337 IS_LEFT_OP (root->left))
5340 if (!SPEC_USIGN (TETYPE (root->left->left)))
5343 if (!IS_AST_LIT_VALUE (root->left->right) ||
5344 !IS_AST_LIT_VALUE (root->right->right))
5347 /* make sure it is the same symbol */
5348 if (!isAstEqual (root->left->left,
5352 if (AST_LIT_VALUE (root->right->right) != 1)
5355 if (AST_LIT_VALUE (root->left->right) !=
5356 (getSize (TTYPE (root->left->left)) * 8 - 1))
5359 /* make sure the port supports RRC */
5360 if (port->hasExtBitOp
5361 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5364 /* whew got the first case : create the AST */
5365 return newNode (RRC, root->left->left, NULL);
5369 /* not found return root */
5373 /*-----------------------------------------------------------------*/
5374 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5375 /*-----------------------------------------------------------------*/
5377 optimizeSWAP (ast * root)
5379 /* will look for trees of the form
5380 (?expr << 4) | (?expr >> 4) or
5381 (?expr >> 4) | (?expr << 4) will make that
5382 into a SWAP : operation ..
5383 note : by 4 I mean (number of bits required to hold the
5385 /* if the root operations is not a | operation the not */
5386 if (!IS_BITOR (root))
5389 /* (?expr << 4) | (?expr >> 4) */
5390 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5391 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5394 if (!SPEC_USIGN (TETYPE (root->left->left)))
5397 if (!IS_AST_LIT_VALUE (root->left->right) ||
5398 !IS_AST_LIT_VALUE (root->right->right))
5401 /* make sure it is the same expression */
5402 if (!isAstEqual (root->left->left,
5406 if (AST_LIT_VALUE (root->left->right) !=
5407 (getSize (TTYPE (root->left->left)) * 4))
5410 if (AST_LIT_VALUE (root->right->right) !=
5411 (getSize (TTYPE (root->left->left)) * 4))
5414 /* make sure the port supports SWAP */
5415 if (port->hasExtBitOp
5416 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5419 /* found it : create the AST */
5420 return newNode (SWAP, root->left->left, NULL);
5424 /* not found return root */
5428 /*-----------------------------------------------------------------*/
5429 /* optimizeCompare - optimizes compares for bit variables */
5430 /*-----------------------------------------------------------------*/
5432 optimizeCompare (ast * root)
5434 ast *optExpr = NULL;
5437 unsigned int litValue;
5439 /* if nothing then return nothing */
5443 /* if not a compare op then do leaves */
5444 if (!IS_COMPARE_OP (root))
5446 root->left = optimizeCompare (root->left);
5447 root->right = optimizeCompare (root->right);
5451 /* if left & right are the same then depending
5452 of the operation do */
5453 if (isAstEqual (root->left, root->right))
5455 switch (root->opval.op)
5460 optExpr = newAst_VALUE (constVal ("0"));
5465 optExpr = newAst_VALUE (constVal ("1"));
5469 return decorateType (optExpr, RESULT_TYPE_NONE);
5472 vleft = (root->left->type == EX_VALUE ?
5473 root->left->opval.val : NULL);
5475 vright = (root->right->type == EX_VALUE ?
5476 root->right->opval.val : NULL);
5478 /* if left is a BITVAR in BITSPACE */
5479 /* and right is a LITERAL then opt- */
5480 /* imize else do nothing */
5481 if (vleft && vright &&
5482 IS_BITVAR (vleft->etype) &&
5483 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5484 IS_LITERAL (vright->etype))
5487 /* if right side > 1 then comparison may never succeed */
5488 if ((litValue = (int) floatFromVal (vright)) > 1)
5490 werror (W_BAD_COMPARE);
5496 switch (root->opval.op)
5498 case '>': /* bit value greater than 1 cannot be */
5499 werror (W_BAD_COMPARE);
5503 case '<': /* bit value < 1 means 0 */
5505 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5508 case LE_OP: /* bit value <= 1 means no check */
5509 optExpr = newAst_VALUE (vright);
5512 case GE_OP: /* bit value >= 1 means only check for = */
5514 optExpr = newAst_VALUE (vleft);
5519 { /* literal is zero */
5520 switch (root->opval.op)
5522 case '<': /* bit value < 0 cannot be */
5523 werror (W_BAD_COMPARE);
5527 case '>': /* bit value > 0 means 1 */
5529 optExpr = newAst_VALUE (vleft);
5532 case LE_OP: /* bit value <= 0 means no check */
5533 case GE_OP: /* bit value >= 0 means no check */
5534 werror (W_BAD_COMPARE);
5538 case EQ_OP: /* bit == 0 means ! of bit */
5539 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5543 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5544 } /* end-of-if of BITVAR */
5549 /*-----------------------------------------------------------------*/
5550 /* addSymToBlock : adds the symbol to the first block we find */
5551 /*-----------------------------------------------------------------*/
5553 addSymToBlock (symbol * sym, ast * tree)
5555 /* reached end of tree or a leaf */
5556 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5560 if (IS_AST_OP (tree) &&
5561 tree->opval.op == BLOCK)
5564 symbol *lsym = copySymbol (sym);
5566 lsym->next = AST_VALUES (tree, sym);
5567 AST_VALUES (tree, sym) = lsym;
5571 addSymToBlock (sym, tree->left);
5572 addSymToBlock (sym, tree->right);
5575 /*-----------------------------------------------------------------*/
5576 /* processRegParms - do processing for register parameters */
5577 /*-----------------------------------------------------------------*/
5579 processRegParms (value * args, ast * body)
5583 if (IS_REGPARM (args->etype))
5584 addSymToBlock (args->sym, body);
5589 /*-----------------------------------------------------------------*/
5590 /* resetParmKey - resets the operandkeys for the symbols */
5591 /*-----------------------------------------------------------------*/
5592 DEFSETFUNC (resetParmKey)
5603 /*-----------------------------------------------------------------*/
5604 /* createFunction - This is the key node that calls the iCode for */
5605 /* generating the code for a function. Note code */
5606 /* is generated function by function, later when */
5607 /* add inter-procedural analysis this will change */
5608 /*-----------------------------------------------------------------*/
5610 createFunction (symbol * name, ast * body)
5616 iCode *piCode = NULL;
5618 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5619 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5621 /* if check function return 0 then some problem */
5622 if (checkFunction (name, NULL) == 0)
5625 /* create a dummy block if none exists */
5627 body = newNode (BLOCK, NULL, NULL);
5631 /* check if the function name already in the symbol table */
5632 if ((csym = findSym (SymbolTab, NULL, name->name)))
5635 /* special case for compiler defined functions
5636 we need to add the name to the publics list : this
5637 actually means we are now compiling the compiler
5641 addSet (&publics, name);
5646 addSymChain (&name);
5647 allocVariables (name);
5649 name->lastLine = mylineno;
5652 /* set the stack pointer */
5653 stackPtr = -port->stack.direction * port->stack.call_overhead;
5656 if (IFFUNC_ISISR (name->type))
5657 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5659 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5661 if (options.useXstack)
5662 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5664 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5667 fetype = getSpec (name->type); /* get the specifier for the function */
5668 /* if this is a reentrant function then */
5669 if (IFFUNC_ISREENT (name->type))
5672 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5674 /* do processing for parameters that are passed in registers */
5675 processRegParms (FUNC_ARGS(name->type), body);
5677 /* set the stack pointer */
5681 /* allocate & autoinit the block variables */
5682 processBlockVars (body, &stack, ALLOCATE);
5684 /* save the stack information */
5685 if (options.useXstack)
5686 name->xstack = SPEC_STAK (fetype) = stack;
5688 name->stack = SPEC_STAK (fetype) = stack;
5690 /* name needs to be mangled */
5691 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5693 body = resolveSymbols (body); /* resolve the symbols */
5694 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5697 ex = newAst_VALUE (symbolVal (name)); /* create name */
5698 ex = newNode (FUNCTION, ex, body);
5699 ex->values.args = FUNC_ARGS(name->type);
5701 if (options.dump_tree) PA(ex);
5704 werror (E_FUNC_NO_CODE, name->name);
5708 /* create the node & generate intermediate code */
5710 codeOutFile = code->oFile;
5711 piCode = iCodeFromAst (ex);
5715 werror (E_FUNC_NO_CODE, name->name);
5719 eBBlockFromiCode (piCode);
5721 /* if there are any statics then do them */
5724 GcurMemmap = statsg;
5725 codeOutFile = statsg->oFile;
5726 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5732 /* dealloc the block variables */
5733 processBlockVars (body, &stack, DEALLOCATE);
5734 outputDebugStackSymbols();
5735 /* deallocate paramaters */
5736 deallocParms (FUNC_ARGS(name->type));
5738 if (IFFUNC_ISREENT (name->type))
5741 /* we are done freeup memory & cleanup */
5743 if (port->reset_labelKey) labelKey = 1;
5745 FUNC_HASBODY(name->type) = 1;
5746 addSet (&operKeyReset, name);
5747 applyToSet (operKeyReset, resetParmKey);
5752 cleanUpLevel (LabelTab, 0);
5753 cleanUpBlock (StructTab, 1);
5754 cleanUpBlock (TypedefTab, 1);
5756 xstack->syms = NULL;
5757 istack->syms = NULL;
5762 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5763 /*-----------------------------------------------------------------*/
5764 /* ast_print : prints the ast (for debugging purposes) */
5765 /*-----------------------------------------------------------------*/
5767 void ast_print (ast * tree, FILE *outfile, int indent)
5772 /* can print only decorated trees */
5773 if (!tree->decorated) return;
5775 /* if any child is an error | this one is an error do nothing */
5776 if (tree->isError ||
5777 (tree->left && tree->left->isError) ||
5778 (tree->right && tree->right->isError)) {
5779 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5783 /* print the line */
5784 /* if not block & function */
5785 if (tree->type == EX_OP &&
5786 (tree->opval.op != FUNCTION &&
5787 tree->opval.op != BLOCK &&
5788 tree->opval.op != NULLOP)) {
5791 if (tree->opval.op == FUNCTION) {
5793 value *args=FUNC_ARGS(tree->left->opval.val->type);
5794 fprintf(outfile,"FUNCTION (%s=%p) type (",
5795 tree->left->opval.val->name, tree);
5796 printTypeChain (tree->left->opval.val->type->next,outfile);
5797 fprintf(outfile,") args (");
5800 fprintf (outfile, ", ");
5802 printTypeChain (args ? args->type : NULL, outfile);
5804 args= args ? args->next : NULL;
5806 fprintf(outfile,")\n");
5807 ast_print(tree->left,outfile,indent);
5808 ast_print(tree->right,outfile,indent);
5811 if (tree->opval.op == BLOCK) {
5812 symbol *decls = tree->values.sym;
5813 INDENT(indent,outfile);
5814 fprintf(outfile,"{\n");
5816 INDENT(indent+2,outfile);
5817 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5818 decls->name, decls);
5819 printTypeChain(decls->type,outfile);
5820 fprintf(outfile,")\n");
5822 decls = decls->next;
5824 ast_print(tree->right,outfile,indent+2);
5825 INDENT(indent,outfile);
5826 fprintf(outfile,"}\n");
5829 if (tree->opval.op == NULLOP) {
5830 ast_print(tree->left,outfile,indent);
5831 ast_print(tree->right,outfile,indent);
5834 INDENT(indent,outfile);
5836 /*------------------------------------------------------------------*/
5837 /*----------------------------*/
5838 /* leaf has been reached */
5839 /*----------------------------*/
5840 /* if this is of type value */
5841 /* just get the type */
5842 if (tree->type == EX_VALUE) {
5844 if (IS_LITERAL (tree->opval.val->etype)) {
5845 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5846 if (SPEC_USIGN (tree->opval.val->etype))
5847 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5849 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5850 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5851 floatFromVal(tree->opval.val));
5852 } else if (tree->opval.val->sym) {
5853 /* if the undefined flag is set then give error message */
5854 if (tree->opval.val->sym->undefined) {
5855 fprintf(outfile,"UNDEFINED SYMBOL ");
5857 fprintf(outfile,"SYMBOL ");
5859 fprintf(outfile,"(%s=%p)",
5860 tree->opval.val->sym->name,tree);
5863 fprintf(outfile," type (");
5864 printTypeChain(tree->ftype,outfile);
5865 fprintf(outfile,")\n");
5867 fprintf(outfile,"\n");
5872 /* if type link for the case of cast */
5873 if (tree->type == EX_LINK) {
5874 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5875 printTypeChain(tree->opval.lnk,outfile);
5876 fprintf(outfile,")\n");
5881 /* depending on type of operator do */
5883 switch (tree->opval.op) {
5884 /*------------------------------------------------------------------*/
5885 /*----------------------------*/
5887 /*----------------------------*/
5889 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5890 printTypeChain(tree->ftype,outfile);
5891 fprintf(outfile,")\n");
5892 ast_print(tree->left,outfile,indent+2);
5893 ast_print(tree->right,outfile,indent+2);
5896 /*------------------------------------------------------------------*/
5897 /*----------------------------*/
5899 /*----------------------------*/
5901 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5902 printTypeChain(tree->ftype,outfile);
5903 fprintf(outfile,")\n");
5904 ast_print(tree->left,outfile,indent+2);
5905 ast_print(tree->right,outfile,indent+2);
5908 /*------------------------------------------------------------------*/
5909 /*----------------------------*/
5910 /* struct/union pointer */
5911 /*----------------------------*/
5913 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5914 printTypeChain(tree->ftype,outfile);
5915 fprintf(outfile,")\n");
5916 ast_print(tree->left,outfile,indent+2);
5917 ast_print(tree->right,outfile,indent+2);
5920 /*------------------------------------------------------------------*/
5921 /*----------------------------*/
5922 /* ++/-- operation */
5923 /*----------------------------*/
5926 fprintf(outfile,"post-");
5928 fprintf(outfile,"pre-");
5929 fprintf(outfile,"INC_OP (%p) type (",tree);
5930 printTypeChain(tree->ftype,outfile);
5931 fprintf(outfile,")\n");
5932 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5933 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5938 fprintf(outfile,"post-");
5940 fprintf(outfile,"pre-");
5941 fprintf(outfile,"DEC_OP (%p) type (",tree);
5942 printTypeChain(tree->ftype,outfile);
5943 fprintf(outfile,")\n");
5944 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5945 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5948 /*------------------------------------------------------------------*/
5949 /*----------------------------*/
5951 /*----------------------------*/
5954 fprintf(outfile,"& (%p) type (",tree);
5955 printTypeChain(tree->ftype,outfile);
5956 fprintf(outfile,")\n");
5957 ast_print(tree->left,outfile,indent+2);
5958 ast_print(tree->right,outfile,indent+2);
5960 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5961 printTypeChain(tree->ftype,outfile);
5962 fprintf(outfile,")\n");
5963 ast_print(tree->left,outfile,indent+2);
5964 ast_print(tree->right,outfile,indent+2);
5967 /*----------------------------*/
5969 /*----------------------------*/
5971 fprintf(outfile,"OR (%p) type (",tree);
5972 printTypeChain(tree->ftype,outfile);
5973 fprintf(outfile,")\n");
5974 ast_print(tree->left,outfile,indent+2);
5975 ast_print(tree->right,outfile,indent+2);
5977 /*------------------------------------------------------------------*/
5978 /*----------------------------*/
5980 /*----------------------------*/
5982 fprintf(outfile,"XOR (%p) type (",tree);
5983 printTypeChain(tree->ftype,outfile);
5984 fprintf(outfile,")\n");
5985 ast_print(tree->left,outfile,indent+2);
5986 ast_print(tree->right,outfile,indent+2);
5989 /*------------------------------------------------------------------*/
5990 /*----------------------------*/
5992 /*----------------------------*/
5994 fprintf(outfile,"DIV (%p) type (",tree);
5995 printTypeChain(tree->ftype,outfile);
5996 fprintf(outfile,")\n");
5997 ast_print(tree->left,outfile,indent+2);
5998 ast_print(tree->right,outfile,indent+2);
6000 /*------------------------------------------------------------------*/
6001 /*----------------------------*/
6003 /*----------------------------*/
6005 fprintf(outfile,"MOD (%p) type (",tree);
6006 printTypeChain(tree->ftype,outfile);
6007 fprintf(outfile,")\n");
6008 ast_print(tree->left,outfile,indent+2);
6009 ast_print(tree->right,outfile,indent+2);
6012 /*------------------------------------------------------------------*/
6013 /*----------------------------*/
6014 /* address dereference */
6015 /*----------------------------*/
6016 case '*': /* can be unary : if right is null then unary operation */
6018 fprintf(outfile,"DEREF (%p) type (",tree);
6019 printTypeChain(tree->ftype,outfile);
6020 fprintf(outfile,")\n");
6021 ast_print(tree->left,outfile,indent+2);
6024 /*------------------------------------------------------------------*/
6025 /*----------------------------*/
6026 /* multiplication */
6027 /*----------------------------*/
6028 fprintf(outfile,"MULT (%p) type (",tree);
6029 printTypeChain(tree->ftype,outfile);
6030 fprintf(outfile,")\n");
6031 ast_print(tree->left,outfile,indent+2);
6032 ast_print(tree->right,outfile,indent+2);
6036 /*------------------------------------------------------------------*/
6037 /*----------------------------*/
6038 /* unary '+' operator */
6039 /*----------------------------*/
6043 fprintf(outfile,"UPLUS (%p) type (",tree);
6044 printTypeChain(tree->ftype,outfile);
6045 fprintf(outfile,")\n");
6046 ast_print(tree->left,outfile,indent+2);
6048 /*------------------------------------------------------------------*/
6049 /*----------------------------*/
6051 /*----------------------------*/
6052 fprintf(outfile,"ADD (%p) type (",tree);
6053 printTypeChain(tree->ftype,outfile);
6054 fprintf(outfile,")\n");
6055 ast_print(tree->left,outfile,indent+2);
6056 ast_print(tree->right,outfile,indent+2);
6059 /*------------------------------------------------------------------*/
6060 /*----------------------------*/
6062 /*----------------------------*/
6063 case '-': /* can be unary */
6065 fprintf(outfile,"UMINUS (%p) type (",tree);
6066 printTypeChain(tree->ftype,outfile);
6067 fprintf(outfile,")\n");
6068 ast_print(tree->left,outfile,indent+2);
6070 /*------------------------------------------------------------------*/
6071 /*----------------------------*/
6073 /*----------------------------*/
6074 fprintf(outfile,"SUB (%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);
6081 /*------------------------------------------------------------------*/
6082 /*----------------------------*/
6084 /*----------------------------*/
6086 fprintf(outfile,"COMPL (%p) type (",tree);
6087 printTypeChain(tree->ftype,outfile);
6088 fprintf(outfile,")\n");
6089 ast_print(tree->left,outfile,indent+2);
6091 /*------------------------------------------------------------------*/
6092 /*----------------------------*/
6094 /*----------------------------*/
6096 fprintf(outfile,"NOT (%p) type (",tree);
6097 printTypeChain(tree->ftype,outfile);
6098 fprintf(outfile,")\n");
6099 ast_print(tree->left,outfile,indent+2);
6101 /*------------------------------------------------------------------*/
6102 /*----------------------------*/
6104 /*----------------------------*/
6106 fprintf(outfile,"RRC (%p) type (",tree);
6107 printTypeChain(tree->ftype,outfile);
6108 fprintf(outfile,")\n");
6109 ast_print(tree->left,outfile,indent+2);
6113 fprintf(outfile,"RLC (%p) type (",tree);
6114 printTypeChain(tree->ftype,outfile);
6115 fprintf(outfile,")\n");
6116 ast_print(tree->left,outfile,indent+2);
6119 fprintf(outfile,"SWAP (%p) type (",tree);
6120 printTypeChain(tree->ftype,outfile);
6121 fprintf(outfile,")\n");
6122 ast_print(tree->left,outfile,indent+2);
6125 fprintf(outfile,"GETHBIT (%p) type (",tree);
6126 printTypeChain(tree->ftype,outfile);
6127 fprintf(outfile,")\n");
6128 ast_print(tree->left,outfile,indent+2);
6131 fprintf(outfile,"GETABIT (%p) type (",tree);
6132 printTypeChain(tree->ftype,outfile);
6133 fprintf(outfile,")\n");
6134 ast_print(tree->left,outfile,indent+2);
6135 ast_print(tree->right,outfile,indent+2);
6138 fprintf(outfile,"GETBYTE (%p) type (",tree);
6139 printTypeChain(tree->ftype,outfile);
6140 fprintf(outfile,")\n");
6141 ast_print(tree->left,outfile,indent+2);
6142 ast_print(tree->right,outfile,indent+2);
6145 fprintf(outfile,"GETWORD (%p) type (",tree);
6146 printTypeChain(tree->ftype,outfile);
6147 fprintf(outfile,")\n");
6148 ast_print(tree->left,outfile,indent+2);
6149 ast_print(tree->right,outfile,indent+2);
6152 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6153 printTypeChain(tree->ftype,outfile);
6154 fprintf(outfile,")\n");
6155 ast_print(tree->left,outfile,indent+2);
6156 ast_print(tree->right,outfile,indent+2);
6159 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6160 printTypeChain(tree->ftype,outfile);
6161 fprintf(outfile,")\n");
6162 ast_print(tree->left,outfile,indent+2);
6163 ast_print(tree->right,outfile,indent+2);
6165 /*------------------------------------------------------------------*/
6166 /*----------------------------*/
6168 /*----------------------------*/
6169 case CAST: /* change the type */
6170 fprintf(outfile,"CAST (%p) from type (",tree);
6171 printTypeChain(tree->right->ftype,outfile);
6172 fprintf(outfile,") to type (");
6173 printTypeChain(tree->ftype,outfile);
6174 fprintf(outfile,")\n");
6175 ast_print(tree->right,outfile,indent+2);
6179 fprintf(outfile,"ANDAND (%p) type (",tree);
6180 printTypeChain(tree->ftype,outfile);
6181 fprintf(outfile,")\n");
6182 ast_print(tree->left,outfile,indent+2);
6183 ast_print(tree->right,outfile,indent+2);
6186 fprintf(outfile,"OROR (%p) type (",tree);
6187 printTypeChain(tree->ftype,outfile);
6188 fprintf(outfile,")\n");
6189 ast_print(tree->left,outfile,indent+2);
6190 ast_print(tree->right,outfile,indent+2);
6193 /*------------------------------------------------------------------*/
6194 /*----------------------------*/
6195 /* comparison operators */
6196 /*----------------------------*/
6198 fprintf(outfile,"GT(>) (%p) type (",tree);
6199 printTypeChain(tree->ftype,outfile);
6200 fprintf(outfile,")\n");
6201 ast_print(tree->left,outfile,indent+2);
6202 ast_print(tree->right,outfile,indent+2);
6205 fprintf(outfile,"LT(<) (%p) type (",tree);
6206 printTypeChain(tree->ftype,outfile);
6207 fprintf(outfile,")\n");
6208 ast_print(tree->left,outfile,indent+2);
6209 ast_print(tree->right,outfile,indent+2);
6212 fprintf(outfile,"LE(<=) (%p) type (",tree);
6213 printTypeChain(tree->ftype,outfile);
6214 fprintf(outfile,")\n");
6215 ast_print(tree->left,outfile,indent+2);
6216 ast_print(tree->right,outfile,indent+2);
6219 fprintf(outfile,"GE(>=) (%p) type (",tree);
6220 printTypeChain(tree->ftype,outfile);
6221 fprintf(outfile,")\n");
6222 ast_print(tree->left,outfile,indent+2);
6223 ast_print(tree->right,outfile,indent+2);
6226 fprintf(outfile,"EQ(==) (%p) type (",tree);
6227 printTypeChain(tree->ftype,outfile);
6228 fprintf(outfile,")\n");
6229 ast_print(tree->left,outfile,indent+2);
6230 ast_print(tree->right,outfile,indent+2);
6233 fprintf(outfile,"NE(!=) (%p) type (",tree);
6234 printTypeChain(tree->ftype,outfile);
6235 fprintf(outfile,")\n");
6236 ast_print(tree->left,outfile,indent+2);
6237 ast_print(tree->right,outfile,indent+2);
6238 /*------------------------------------------------------------------*/
6239 /*----------------------------*/
6241 /*----------------------------*/
6242 case SIZEOF: /* evaluate wihout code generation */
6243 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6246 /*------------------------------------------------------------------*/
6247 /*----------------------------*/
6248 /* conditional operator '?' */
6249 /*----------------------------*/
6251 fprintf(outfile,"QUEST(?) (%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);
6259 fprintf(outfile,"COLON(:) (%p) type (",tree);
6260 printTypeChain(tree->ftype,outfile);
6261 fprintf(outfile,")\n");
6262 ast_print(tree->left,outfile,indent+2);
6263 ast_print(tree->right,outfile,indent+2);
6266 /*------------------------------------------------------------------*/
6267 /*----------------------------*/
6268 /* assignment operators */
6269 /*----------------------------*/
6271 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6272 printTypeChain(tree->ftype,outfile);
6273 fprintf(outfile,")\n");
6274 ast_print(tree->left,outfile,indent+2);
6275 ast_print(tree->right,outfile,indent+2);
6278 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6279 printTypeChain(tree->ftype,outfile);
6280 fprintf(outfile,")\n");
6281 ast_print(tree->left,outfile,indent+2);
6282 ast_print(tree->right,outfile,indent+2);
6285 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6286 printTypeChain(tree->ftype,outfile);
6287 fprintf(outfile,")\n");
6288 ast_print(tree->left,outfile,indent+2);
6289 ast_print(tree->right,outfile,indent+2);
6292 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6293 printTypeChain(tree->ftype,outfile);
6294 fprintf(outfile,")\n");
6295 ast_print(tree->left,outfile,indent+2);
6296 ast_print(tree->right,outfile,indent+2);
6299 fprintf(outfile,"XORASS(^=) (%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,"RSHFTASS(>>=) (%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 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6314 printTypeChain(tree->ftype,outfile);
6315 fprintf(outfile,")\n");
6316 ast_print(tree->left,outfile,indent+2);
6317 ast_print(tree->right,outfile,indent+2);
6319 /*------------------------------------------------------------------*/
6320 /*----------------------------*/
6322 /*----------------------------*/
6324 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6325 printTypeChain(tree->ftype,outfile);
6326 fprintf(outfile,")\n");
6327 ast_print(tree->left,outfile,indent+2);
6328 ast_print(tree->right,outfile,indent+2);
6330 /*------------------------------------------------------------------*/
6331 /*----------------------------*/
6333 /*----------------------------*/
6335 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6336 printTypeChain(tree->ftype,outfile);
6337 fprintf(outfile,")\n");
6338 ast_print(tree->left,outfile,indent+2);
6339 ast_print(tree->right,outfile,indent+2);
6341 /*------------------------------------------------------------------*/
6342 /*----------------------------*/
6343 /* straight assignemnt */
6344 /*----------------------------*/
6346 fprintf(outfile,"ASSIGN(=) (%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);
6352 /*------------------------------------------------------------------*/
6353 /*----------------------------*/
6354 /* comma operator */
6355 /*----------------------------*/
6357 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6358 printTypeChain(tree->ftype,outfile);
6359 fprintf(outfile,")\n");
6360 ast_print(tree->left,outfile,indent+2);
6361 ast_print(tree->right,outfile,indent+2);
6363 /*------------------------------------------------------------------*/
6364 /*----------------------------*/
6366 /*----------------------------*/
6369 fprintf(outfile,"CALL (%p) type (",tree);
6370 printTypeChain(tree->ftype,outfile);
6371 fprintf(outfile,")\n");
6372 ast_print(tree->left,outfile,indent+2);
6373 ast_print(tree->right,outfile,indent+2);
6376 fprintf(outfile,"PARMS\n");
6377 ast_print(tree->left,outfile,indent+2);
6378 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6379 ast_print(tree->right,outfile,indent+2);
6382 /*------------------------------------------------------------------*/
6383 /*----------------------------*/
6384 /* return statement */
6385 /*----------------------------*/
6387 fprintf(outfile,"RETURN (%p) type (",tree);
6389 printTypeChain(tree->right->ftype,outfile);
6391 fprintf(outfile,")\n");
6392 ast_print(tree->right,outfile,indent+2);
6394 /*------------------------------------------------------------------*/
6395 /*----------------------------*/
6396 /* label statement */
6397 /*----------------------------*/
6399 fprintf(outfile,"LABEL (%p)\n",tree);
6400 ast_print(tree->left,outfile,indent+2);
6401 ast_print(tree->right,outfile,indent);
6403 /*------------------------------------------------------------------*/
6404 /*----------------------------*/
6405 /* switch statement */
6406 /*----------------------------*/
6410 fprintf(outfile,"SWITCH (%p) ",tree);
6411 ast_print(tree->left,outfile,0);
6412 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6413 INDENT(indent+2,outfile);
6414 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6415 (int) floatFromVal(val),
6416 tree->values.switchVals.swNum,
6417 (int) floatFromVal(val));
6419 ast_print(tree->right,outfile,indent);
6422 /*------------------------------------------------------------------*/
6423 /*----------------------------*/
6425 /*----------------------------*/
6427 fprintf(outfile,"IF (%p) \n",tree);
6428 ast_print(tree->left,outfile,indent+2);
6429 if (tree->trueLabel) {
6430 INDENT(indent+2,outfile);
6431 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6433 if (tree->falseLabel) {
6434 INDENT(indent+2,outfile);
6435 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6437 ast_print(tree->right,outfile,indent+2);
6439 /*----------------------------*/
6440 /* goto Statement */
6441 /*----------------------------*/
6443 fprintf(outfile,"GOTO (%p) \n",tree);
6444 ast_print(tree->left,outfile,indent+2);
6445 fprintf(outfile,"\n");
6447 /*------------------------------------------------------------------*/
6448 /*----------------------------*/
6450 /*----------------------------*/
6452 fprintf(outfile,"FOR (%p) \n",tree);
6453 if (AST_FOR( tree, initExpr)) {
6454 INDENT(indent+2,outfile);
6455 fprintf(outfile,"INIT EXPR ");
6456 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6458 if (AST_FOR( tree, condExpr)) {
6459 INDENT(indent+2,outfile);
6460 fprintf(outfile,"COND EXPR ");
6461 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6463 if (AST_FOR( tree, loopExpr)) {
6464 INDENT(indent+2,outfile);
6465 fprintf(outfile,"LOOP EXPR ");
6466 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6468 fprintf(outfile,"FOR LOOP BODY \n");
6469 ast_print(tree->left,outfile,indent+2);
6472 fprintf(outfile,"CRITICAL (%p) \n",tree);
6473 ast_print(tree->left,outfile,indent+2);
6481 ast_print(t,stdout,0);
6486 /*-----------------------------------------------------------------*/
6487 /* astErrors : returns non-zero if errors present in tree */
6488 /*-----------------------------------------------------------------*/
6489 int astErrors(ast *t)
6498 if (t->type == EX_VALUE
6499 && t->opval.val->sym
6500 && t->opval.val->sym->undefined)
6503 errors += astErrors(t->left);
6504 errors += astErrors(t->right);