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 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
52 ast *createIval (ast *, link *, initList *, ast *);
53 ast *createIvalCharPtr (ast *, link *, ast *);
54 ast *optimizeRRCRLC ( ast * );
55 ast *optimizeGetHbit(ast *);
56 ast *backPatchLabels (ast *,symbol *,symbol *);
60 printTypeChain(tree->ftype,stdout);
65 /*-----------------------------------------------------------------*/
66 /* newAst - creates a fresh node for an expression tree */
67 /*-----------------------------------------------------------------*/
69 ast *newAst (int type, void *op )
72 static int oldLineno = 0 ;
74 ALLOC(ex,sizeof(ast));
77 ex->lineno = (noLineno ? oldLineno : yylineno);
78 ex->filename = currFname ;
79 ex->level = NestLevel ;
80 ex->block = currBlockno ;
81 ex->initMode = inInitMode;
83 /* depending on the type */
86 ex->opval.val = (value *) op;
89 ex->opval.op = (long) op ;
92 ex->opval.lnk = (link *) op;
95 ex->opval.stmnt= (unsigned) op;
102 static ast* newAst_(unsigned type)
105 static int oldLineno = 0 ;
107 ALLOC(ex,sizeof(ast));
110 ex->lineno = (noLineno ? oldLineno : yylineno);
111 ex->filename = currFname ;
112 ex->level = NestLevel ;
113 ex->block = currBlockno ;
114 ex->initMode = inInitMode;
118 ast* newAst_VALUE(value*val)
120 ast* ex = newAst_(EX_VALUE);
125 ast* newAst_OP(unsigned op)
127 ast*ex = newAst_(EX_OP);
132 ast* newAst_LINK(link*val)
134 ast* ex = newAst_(EX_LINK);
139 ast* newAst_STMNT(unsigned val)
141 ast* ex = newAst_(EX_STMNT);
142 ex->opval.stmnt = val;
146 /*-----------------------------------------------------------------*/
147 /* newNode - creates a new node */
148 /*-----------------------------------------------------------------*/
149 ast *newNode ( long op, ast *left, ast *right )
160 /*-----------------------------------------------------------------*/
161 /* newIfxNode - creates a new Ifx Node */
162 /*-----------------------------------------------------------------*/
163 ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel)
167 /* if this is a literal then we already know the result */
168 if (condAst->etype && IS_LITERAL(condAst->etype)) {
170 /* then depending on the expression value */
171 if ( floatFromVal(condAst->opval.val) )
172 ifxNode = newNode(GOTO,
173 newAst_VALUE(symbolVal(trueLabel)),
176 ifxNode = newNode(GOTO,
177 newAst_VALUE(symbolVal(falseLabel)),
181 ifxNode = newNode(IFX,condAst,NULL);
182 ifxNode->trueLabel = trueLabel;
183 ifxNode->falseLabel= falseLabel;
189 /*-----------------------------------------------------------------*/
190 /* copyAstValues - copies value portion of ast if needed */
191 /*-----------------------------------------------------------------*/
192 void copyAstValues (ast *dest,ast *src)
194 switch (src->opval.op) {
196 dest->values.sym = copySymbolChain(src->values.sym);
200 dest->values.switchVals.swVals =
201 copyValue(src->values.switchVals.swVals);
202 dest->values.switchVals.swDefault =
203 src->values.switchVals.swDefault ;
204 dest->values.switchVals.swNum =
205 src->values.switchVals.swNum ;
209 ALLOC_ATOMIC(dest->values.inlineasm,strlen(src->values.inlineasm));
210 strcpy(dest->values.inlineasm,src->values.inlineasm);
213 AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel));
214 AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel));
215 AST_FOR(dest,falseLabel) = copySymbol(AST_FOR(src,falseLabel));
216 AST_FOR(dest,condLabel) = copySymbol(AST_FOR(src,condLabel));
217 AST_FOR(dest,initExpr) = copyAst (AST_FOR(src,initExpr)) ;
218 AST_FOR(dest,condExpr) = copyAst (AST_FOR(src,condExpr)) ;
219 AST_FOR(dest,loopExpr) = copyAst (AST_FOR(src,loopExpr)) ;
224 /*-----------------------------------------------------------------*/
225 /* copyAst - makes a copy of a given astession */
226 /*-----------------------------------------------------------------*/
227 ast *copyAst (ast *src)
231 if (!src) return NULL ;
233 ALLOC(dest,sizeof(ast));
235 dest->type = src->type ;
236 dest->lineno = src->lineno ;
237 dest->level = src->level ;
238 dest->funcName = src->funcName;
239 dest->argSym = src->argSym;
241 /* if this is a leaf */
243 if (src->type == EX_VALUE) {
244 dest->opval.val = copyValue(src->opval.val);
249 if (src->type == EX_LINK) {
250 dest->opval.lnk = copyLinkChain(src->opval.lnk);
254 dest->opval.op = src->opval.op ;
256 /* if this is a node that has special values */
257 copyAstValues (dest,src);
260 dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ;
262 dest->trueLabel = copySymbol (src->trueLabel);
263 dest->falseLabel= copySymbol (src->falseLabel);
264 dest->left = copyAst(src->left);
265 dest->right= copyAst(src->right);
271 /*-----------------------------------------------------------------*/
272 /* hasSEFcalls - returns TRUE if tree has a function call */
273 /*-----------------------------------------------------------------*/
274 bool hasSEFcalls ( ast *tree)
279 if (tree->type == EX_OP &&
280 ( tree->opval.op == CALL ||
281 tree->opval.op == PCALL ||
282 tree->opval.op == '=' ||
283 tree->opval.op == INC_OP ||
284 tree->opval.op == DEC_OP ))
287 return ( hasSEFcalls(tree->left) |
288 hasSEFcalls(tree->right));
291 /*-----------------------------------------------------------------*/
292 /* isAstEqual - compares two asts & returns 1 if they are equal */
293 /*-----------------------------------------------------------------*/
294 int isAstEqual (ast *t1, ast *t2)
303 if (t1->type != t2->type)
308 if (t1->opval.op != t2->opval.op)
310 return ( isAstEqual(t1->left,t2->left) &&
311 isAstEqual(t1->right,t2->right));
315 if (t1->opval.val->sym) {
316 if (!t2->opval.val->sym)
319 return isSymbolEqual(t1->opval.val->sym,
323 if (t2->opval.val->sym)
326 return (floatFromVal(t1->opval.val) ==
327 floatFromVal(t2->opval.val));
331 /* only compare these two types */
339 /*-----------------------------------------------------------------*/
340 /* resolveSymbols - resolve symbols from the symbol table */
341 /*-----------------------------------------------------------------*/
342 ast *resolveSymbols (ast *tree)
344 /* walk the entire tree and check for values */
345 /* with symbols if we find one then replace */
346 /* symbol with that from the symbol table */
352 /* if not block & function */
353 if ( tree->type == EX_OP &&
354 ( tree->opval.op != FUNCTION &&
355 tree->opval.op != BLOCK &&
356 tree->opval.op != NULLOP )) {
357 filename = tree->filename ;
358 lineno = tree->lineno ;
361 /* make sure we resolve the true & false labels for ifx */
362 if (tree->type == EX_OP && tree->opval.op == IFX ) {
365 if (tree->trueLabel) {
366 if (( csym = findSym(LabelTab,tree->trueLabel,
367 tree->trueLabel->name)))
368 tree->trueLabel = csym ;
370 werror(E_LABEL_UNDEF,tree->trueLabel->name);
373 if (tree->falseLabel) {
374 if (( csym = findSym(LabelTab,
376 tree->falseLabel->name)))
377 tree->falseLabel = csym ;
379 werror(E_LABEL_UNDEF,tree->falseLabel->name);
384 /* if this is a label resolve it from the labelTab*/
385 if (IS_AST_VALUE(tree) &&
386 tree->opval.val->sym &&
387 tree->opval.val->sym->islbl) {
389 symbol *csym = findSym (LabelTab, tree->opval.val->sym ,
390 tree->opval.val->sym->name);
393 werror (E_LABEL_UNDEF,tree->opval.val->sym->name);
395 tree->opval.val->sym = csym ;
397 goto resolveChildren ;
400 /* do only for leafs */
401 if (IS_AST_VALUE(tree) &&
402 tree->opval.val->sym &&
403 ! tree->opval.val->sym->implicit ) {
405 symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym);
407 /* if found in the symbol table & they r not the same */
408 if (csym && tree->opval.val->sym != csym ) {
409 tree->opval.val->sym = csym ;
410 tree->opval.val->type = csym->type;
411 tree->opval.val->etype = csym->etype;
414 /* if not found in the symbol table */
415 /* mark it as undefined assume it is*/
416 /* an integer in data space */
417 if (!csym && !tree->opval.val->sym->implicit) {
419 /* if this is a function name then */
420 /* mark it as returning an int */
421 if (tree->funcName) {
422 tree->opval.val->sym->type = newLink();
423 DCL_TYPE(tree->opval.val->sym->type) = FUNCTION;
424 tree->opval.val->sym->type->next =
425 tree->opval.val->sym->etype = newIntLink();
426 tree->opval.val->etype = tree->opval.val->etype;
427 tree->opval.val->type = tree->opval.val->sym->type;
428 werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name);
430 tree->opval.val->sym->undefined =1 ;
431 tree->opval.val->type =
432 tree->opval.val->etype = newIntLink();
433 tree->opval.val->sym->type =
434 tree->opval.val->sym->etype = newIntLink();
440 resolveSymbols (tree->left);
441 resolveSymbols (tree->right);
446 /*-----------------------------------------------------------------*/
447 /* setAstLineno - walks a ast tree & sets the line number */
448 /*-----------------------------------------------------------------*/
449 int setAstLineno ( ast *tree, int lineno)
454 tree->lineno = lineno ;
455 setAstLineno ( tree->left, lineno);
456 setAstLineno ( tree->right, lineno);
461 /* this functions seems to be superfluous?! kmh */
463 /*-----------------------------------------------------------------*/
464 /* resolveFromTable - will return the symbal table value */
465 /*-----------------------------------------------------------------*/
466 value *resolveFromTable (value *val)
473 csym = findSymWithLevel (SymbolTab,val->sym);
475 /* if found in the symbol table & they r not the same */
476 if (csym && val->sym != csym &&
477 csym->level == val->sym->level &&
482 val->type = csym->type;
483 val->etype = csym->etype;
490 /*-----------------------------------------------------------------*/
491 /* funcOfType :- function of type with name */
492 /*-----------------------------------------------------------------*/
493 symbol *funcOfType (char *name, link *type, link *argType,
494 int nArgs , int rent)
498 /* create the symbol */
499 sym = newSymbol (name,0);
501 /* if arguments required */
505 args = sym->args = newValue();
508 argStack += getSize(type);
509 args->type = copyLinkChain(argType);
510 args->etype = getSpec(args->type);
513 args = args->next = newValue();
517 /* setup return value */
518 sym->type = newLink();
519 DCL_TYPE(sym->type) = FUNCTION;
520 sym->type->next = copyLinkChain(type);
521 sym->etype = getSpec(sym->type);
522 SPEC_RENT(sym->etype) = rent;
527 sym->argStack = (rent ? argStack : 0);
528 allocVariables (sym);
533 /*-----------------------------------------------------------------*/
534 /* reverseParms - will reverse a parameter tree */
535 /*-----------------------------------------------------------------*/
536 void reverseParms (ast *ptree)
542 /* top down if we find a nonParm tree then quit */
543 if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
545 ptree->left = ptree->right;
546 ptree->right = ttree;
547 reverseParms(ptree->left);
548 reverseParms(ptree->right);
554 /*-----------------------------------------------------------------*/
555 /* processParms - makes sure the parameters are okay and do some */
556 /* processing with them */
557 /*-----------------------------------------------------------------*/
558 int processParms (ast *func, value *defParm,
562 link *fetype = func->etype;
564 /* if none of them exist */
565 if ( !defParm && !actParm)
568 /* if the function is being called via a pointer & */
569 /* it has not been defined a reentrant then we cannot*/
570 /* have parameters */
571 if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
572 werror (E_NONRENT_ARGS);
576 /* if defined parameters ended but actual parameters */
577 /* exist and this is not defined as a variable arg */
578 /* also check if statckAuto option is specified */
579 if ((! defParm) && actParm && (!func->hasVargs ) &&
580 !options.stackAuto && !IS_RENT(fetype)) {
581 werror(E_TOO_MANY_PARMS);
585 /* if defined parameters present and actual paramters ended */
586 if ( defParm && ! actParm) {
587 werror(E_TO_FEW_PARMS);
591 /* if defined parameters ended but actual has not & */
592 /* has a variable argument list or statckAuto */
593 if (! defParm && actParm &&
594 (func->hasVargs || options.stackAuto || IS_RENT(fetype)))
597 resolveSymbols(actParm);
598 /* if this is a PARAM node then match left & right */
599 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
601 return (processParms (func,defParm,actParm->left,parmNumber) ||
602 processParms (func,defParm->next, actParm->right,parmNumber) );
605 /* the parameter type must be atleast castable */
606 if (checkType(defParm->type,actParm->ftype) == 0) {
607 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
608 werror(E_CONTINUE,"defined type ");
609 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
610 werror(E_CONTINUE,"actual type ");
611 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
614 /* if the parameter is castable then add the cast */
615 if ( checkType (defParm->type,actParm->ftype) < 0) {
616 ast *pTree = resolveSymbols(copyAst(actParm));
618 /* now change the current one to a cast */
619 actParm->type = EX_OP ;
620 actParm->opval.op = CAST ;
621 actParm->left = newAst_LINK(defParm->type);
622 actParm->right= pTree ;
623 actParm->etype= defParm->etype;
624 actParm->ftype= defParm->type;
627 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
628 actParm->argSym = defParm->sym;
629 /* make a copy and change the regparm type to the defined parm */
630 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
631 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
635 /*-----------------------------------------------------------------*/
636 /* createIvalType - generates ival for basic types */
637 /*-----------------------------------------------------------------*/
638 ast *createIvalType ( ast *sym,link *type, initList *ilist)
642 /* if initList is deep */
643 if ( ilist->type == INIT_DEEP )
644 ilist = ilist->init.deep ;
646 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
647 return decorateType(newNode('=',sym,iExpr));
650 /*-----------------------------------------------------------------*/
651 /* createIvalStruct - generates initial value for structures */
652 /*-----------------------------------------------------------------*/
653 ast *createIvalStruct (ast *sym,link *type,initList *ilist)
659 sflds = SPEC_STRUCT(type)->fields ;
660 if (ilist->type != INIT_DEEP) {
661 werror(E_INIT_STRUCT,"");
665 iloop = ilist->init.deep;
667 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
670 /* if we have come to end */
674 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
675 lAst = decorateType(resolveSymbols(lAst));
676 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
682 /*-----------------------------------------------------------------*/
683 /* createIvalArray - generates code for array initialization */
684 /*-----------------------------------------------------------------*/
685 ast *createIvalArray (ast *sym, link *type, initList *ilist)
689 int lcnt = 0, size =0 ;
691 /* take care of the special case */
692 /* array of characters can be init */
694 if ( IS_CHAR(type->next) )
695 if ( (rast = createIvalCharPtr(sym,
697 decorateType(resolveSymbols(list2expr(ilist))))))
699 return decorateType(resolveSymbols(rast));
701 /* not the special case */
702 if (ilist->type != INIT_DEEP) {
703 werror(E_INIT_STRUCT,"");
707 iloop = ilist->init.deep ;
708 lcnt = DCL_ELEM(type);
714 aSym = newNode('[',sym,newAst_VALUE(valueFromLit(size-1)));
715 aSym = decorateType(resolveSymbols(aSym));
716 rast = createIval (aSym,type->next,iloop,rast) ;
717 iloop = (iloop ? iloop->next : NULL) ;
720 /* if not array limits given & we */
721 /* are out of initialisers then */
722 if (!DCL_ELEM(type) && !iloop)
725 /* no of elements given and we */
726 /* have generated for all of them */
731 /* if we have not been given a size */
733 DCL_ELEM(type) = size;
735 return decorateType(resolveSymbols(rast));
739 /*-----------------------------------------------------------------*/
740 /* createIvalCharPtr - generates initial values for char pointers */
741 /*-----------------------------------------------------------------*/
742 ast *createIvalCharPtr (ast *sym, link *type, ast *iexpr)
746 /* if this is a pointer & right is a literal array then */
747 /* just assignment will do */
748 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
749 SPEC_SCLS(iexpr->etype) == S_CODE )
750 && IS_ARRAY(iexpr->ftype)))
751 return newNode('=',sym,iexpr);
753 /* left side is an array so we have to assign each */
755 if (( IS_LITERAL(iexpr->etype) ||
756 SPEC_SCLS(iexpr->etype) == S_CODE )
757 && IS_ARRAY(iexpr->ftype)) {
759 /* for each character generate an assignment */
760 /* to the array element */
761 char *s = SPEC_CVAL(iexpr->etype).v_char ;
765 rast = newNode(NULLOP,
769 newAst_VALUE(valueFromLit(i))),
770 newAst_VALUE(valueFromLit(*s))));
774 rast = newNode(NULLOP,
778 newAst_VALUE(valueFromLit(i))),
779 newAst_VALUE(valueFromLit(*s))));
780 return decorateType(resolveSymbols(rast));
786 /*-----------------------------------------------------------------*/
787 /* createIvalPtr - generates initial value for pointers */
788 /*-----------------------------------------------------------------*/
789 ast *createIvalPtr (ast *sym,link *type,initList *ilist)
795 if ( ilist->type == INIT_DEEP )
796 ilist = ilist->init.deep ;
798 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
800 /* if character pointer */
801 if (IS_CHAR(type->next))
802 if ((rast = createIvalCharPtr (sym,type,iexpr)))
805 return newNode('=',sym,iexpr);
808 /*-----------------------------------------------------------------*/
809 /* createIval - generates code for initial value */
810 /*-----------------------------------------------------------------*/
811 ast *createIval (ast *sym, link *type, initList *ilist, ast *wid)
818 /* if structure then */
820 rast = createIvalStruct(sym, type,ilist);
822 /* if this is a pointer */
824 rast = createIvalPtr(sym, type,ilist);
826 /* if this is an array */
828 rast = createIvalArray(sym, type,ilist);
830 /* if type is SPECIFIER */
832 rast = createIvalType (sym,type,ilist);
834 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
836 return decorateType(resolveSymbols(rast)) ;
839 /*-----------------------------------------------------------------*/
840 /* initAggregates - initialises aggregate variables with initv */
841 /*-----------------------------------------------------------------*/
842 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
844 return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
847 /*-----------------------------------------------------------------*/
848 /* gatherAutoInit - creates assignment expressions for initial */
850 /*-----------------------------------------------------------------*/
851 ast *gatherAutoInit ( symbol *autoChain )
858 for ( sym = autoChain ; sym ; sym = sym->next ) {
860 /* resolve the symbols in the ival */
862 resolveIvalSym(sym->ival);
864 /* if this is a static variable & has an */
865 /* initial value the code needs to be lifted */
866 /* here to the main portion since they can be */
867 /* initialised only once at the start */
868 if ( IS_STATIC(sym->etype) && sym->ival &&
869 SPEC_SCLS(sym->etype) != S_CODE) {
872 /* insert the symbol into the symbol table */
873 /* with level = 0 & name = rname */
874 newSym = copySymbol (sym);
875 addSym (SymbolTab,newSym,newSym->name,0,0);
877 /* now lift the code to main */
878 if (IS_AGGREGATE(sym->type))
879 work = initAggregates (sym, sym->ival,NULL);
881 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
882 list2expr(sym->ival));
884 setAstLineno(work,sym->lineDef);
888 staticAutos = newNode(NULLOP,staticAutos,work);
895 /* if there is an initial value */
896 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
897 if (IS_AGGREGATE(sym->type))
898 work = initAggregates (sym,sym->ival,NULL);
900 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
901 list2expr(sym->ival));
903 setAstLineno (work,sym->lineDef);
906 init = newNode(NULLOP,init,work);
915 /*-----------------------------------------------------------------*/
916 /* stringToSymbol - creates a symbol from a literal string */
917 /*-----------------------------------------------------------------*/
918 static value *stringToSymbol (value *val)
920 char name[SDCC_NAME_MAX+1];
921 static int charLbl = 0;
924 sprintf(name,"_str_%d",charLbl++);
925 sym = newSymbol(name,0); /* make it @ level 0 */
926 strcpy(sym->rname,name);
928 /* copy the type from the value passed */
929 sym->type = copyLinkChain(val->type);
930 sym->etype = getSpec(sym->type);
931 /* change to storage class & output class */
932 SPEC_SCLS(sym->etype) = S_CODE ;
933 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
934 SPEC_STAT(sym->etype) = 1;
935 /* make the level & block = 0 */
936 sym->block = sym->level = 0;
939 sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
946 return symbolVal(sym);
950 /*-----------------------------------------------------------------*/
951 /* processBlockVars - will go thru the ast looking for block if */
952 /* a block is found then will allocate the syms */
953 /* will also gather the auto inits present */
954 /*-----------------------------------------------------------------*/
955 ast *processBlockVars ( ast *tree , int *stack, int action)
960 /* if this is a block */
961 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
964 if (action == ALLOCATE) {
965 autoInit = gatherAutoInit (tree->values.sym);
966 *stack += allocVariables (tree->values.sym);
968 /* if there are auto inits then do them */
970 tree->left = newNode(NULLOP,autoInit,tree->left);
971 } else /* action is deallocate */
972 deallocLocal (tree->values.sym) ;
975 processBlockVars (tree->left, stack, action);
976 processBlockVars (tree->right, stack, action);
980 /*-----------------------------------------------------------------*/
981 /* constExprValue - returns the value of a constant expression */
982 /*-----------------------------------------------------------------*/
983 value *constExprValue (ast *cexpr, int check)
985 cexpr = decorateType(resolveSymbols(cexpr));
987 /* if this is not a constant then */
988 if (!IS_LITERAL(cexpr->ftype)) {
989 /* then check if this is a literal array
991 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
992 SPEC_CVAL(cexpr->etype).v_char &&
993 IS_ARRAY(cexpr->ftype)) {
994 value *val = valFromType(cexpr->ftype);
995 SPEC_SCLS(val->etype) = S_LITERAL;
996 val->sym =cexpr->opval.val->sym ;
997 val->sym->type = copyLinkChain(cexpr->ftype);
998 val->sym->etype = getSpec(val->sym->type);
999 strcpy(val->name,cexpr->opval.val->sym->rname);
1003 /* if we are casting a literal value then */
1004 if (IS_AST_OP(cexpr) &&
1005 cexpr->opval.op == CAST &&
1006 IS_LITERAL(cexpr->left->ftype))
1007 return valCastLiteral(cexpr->ftype,
1008 floatFromVal(cexpr->left->opval.val));
1010 if (IS_AST_VALUE(cexpr))
1011 return cexpr->opval.val;
1014 werror(E_CONST_EXPECTED,"found expression");
1019 /* return the value */
1020 return cexpr->opval.val ;
1024 /*-----------------------------------------------------------------*/
1025 /* isLabelInAst - will return true if a given label is found */
1026 /*-----------------------------------------------------------------*/
1027 bool isLabelInAst (symbol *label, ast *tree)
1029 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1032 if (IS_AST_OP(tree) &&
1033 tree->opval.op == LABEL &&
1034 isSymbolEqual(AST_SYMBOL(tree->left),label))
1037 return isLabelInAst(label,tree->right) &&
1038 isLabelInAst(label,tree->left);
1042 /*-----------------------------------------------------------------*/
1043 /* isLoopCountable - return true if the loop count can be determi- */
1044 /* -ned at compile time . */
1045 /*-----------------------------------------------------------------*/
1046 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1047 symbol **sym,ast **init, ast **end)
1050 /* the loop is considered countable if the following
1051 conditions are true :-
1053 a) initExpr :- <sym> = <const>
1054 b) condExpr :- <sym> < <const1>
1055 c) loopExpr :- <sym> ++
1058 /* first check the initExpr */
1059 if ( IS_AST_OP(initExpr) &&
1060 initExpr->opval.op == '=' && /* is assignment */
1061 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1063 *sym = AST_SYMBOL(initExpr->left);
1064 *init= initExpr->right;
1069 /* for now the symbol has to be of
1071 if (!IS_INTEGRAL((*sym)->type))
1074 /* now check condExpr */
1075 if (IS_AST_OP(condExpr)) {
1077 switch (condExpr->opval.op) {
1079 if (IS_AST_SYM_VALUE(condExpr->left) &&
1080 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1081 IS_AST_LIT_VALUE(condExpr->right)) {
1082 *end = condExpr->right;
1088 if (IS_AST_OP(condExpr->left) &&
1089 condExpr->left->opval.op == '>' &&
1090 IS_AST_LIT_VALUE(condExpr->left->right) &&
1091 IS_AST_SYM_VALUE(condExpr->left->left)&&
1092 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1094 *end = newNode('+', condExpr->left->right,
1095 newAst_VALUE(constVal("1")));
1106 /* check loop expression is of the form <sym>++ */
1107 if (!IS_AST_OP(loopExpr))
1110 /* check if <sym> ++ */
1111 if (loopExpr->opval.op == INC_OP) {
1113 if (loopExpr->left) {
1115 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1116 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1121 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1122 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1129 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1131 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1132 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1133 IS_AST_LIT_VALUE(loopExpr->right) &&
1134 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1142 /*-----------------------------------------------------------------*/
1143 /* astHasVolatile - returns true if ast contains any volatile */
1144 /*-----------------------------------------------------------------*/
1145 bool astHasVolatile (ast *tree)
1150 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1153 if (IS_AST_OP(tree))
1154 return astHasVolatile(tree->left) ||
1155 astHasVolatile(tree->right);
1160 /*-----------------------------------------------------------------*/
1161 /* astHasPointer - return true if the ast contains any ptr variable*/
1162 /*-----------------------------------------------------------------*/
1163 bool astHasPointer (ast *tree)
1168 if (IS_AST_LINK(tree))
1171 /* if we hit an array expression then check
1172 only the left side */
1173 if (IS_AST_OP(tree) && tree->opval.op == '[')
1174 return astHasPointer(tree->left);
1176 if (IS_AST_VALUE(tree))
1177 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1179 return astHasPointer(tree->left) ||
1180 astHasPointer(tree->right);
1184 /*-----------------------------------------------------------------*/
1185 /* astHasSymbol - return true if the ast has the given symbol */
1186 /*-----------------------------------------------------------------*/
1187 bool astHasSymbol (ast *tree, symbol *sym)
1189 if (!tree || IS_AST_LINK(tree))
1192 if (IS_AST_VALUE(tree)) {
1193 if (IS_AST_SYM_VALUE(tree))
1194 return isSymbolEqual(AST_SYMBOL(tree),sym);
1199 return astHasSymbol(tree->left,sym) ||
1200 astHasSymbol(tree->right,sym);
1203 /*-----------------------------------------------------------------*/
1204 /* isConformingBody - the loop body has to conform to a set of rules */
1205 /* for the loop to be considered reversible read on for rules */
1206 /*-----------------------------------------------------------------*/
1207 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1210 /* we are going to do a pre-order traversal of the
1211 tree && check for the following conditions. (essentially
1212 a set of very shallow tests )
1213 a) the sym passed does not participate in
1214 any arithmetic operation
1215 b) There are no function calls
1216 c) all jumps are within the body
1217 d) address of loop control variable not taken
1218 e) if an assignment has a pointer on the
1219 left hand side make sure right does not have
1220 loop control variable */
1222 /* if we reach the end or a leaf then true */
1223 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1227 /* if anything else is "volatile" */
1228 if (IS_VOLATILE(TETYPE(pbody)))
1231 /* we will walk the body in a pre-order traversal for
1233 switch (pbody->opval.op) {
1234 /*------------------------------------------------------------------*/
1236 return isConformingBody (pbody->right,sym,body);
1238 /*------------------------------------------------------------------*/
1243 /*------------------------------------------------------------------*/
1244 case INC_OP: /* incerement operator unary so left only */
1247 /* sure we are not sym is not modified */
1249 IS_AST_SYM_VALUE(pbody->left) &&
1250 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1254 IS_AST_SYM_VALUE(pbody->right) &&
1255 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1260 /*------------------------------------------------------------------*/
1262 case '*' : /* can be unary : if right is null then unary operation */
1267 /* if right is NULL then unary operation */
1268 /*------------------------------------------------------------------*/
1269 /*----------------------------*/
1271 /*----------------------------*/
1272 if ( ! pbody->right ) {
1273 if (IS_AST_SYM_VALUE(pbody->left) &&
1274 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1277 return isConformingBody(pbody->left,sym,body) ;
1279 if (astHasSymbol(pbody->left,sym) ||
1280 astHasSymbol(pbody->right,sym))
1285 /*------------------------------------------------------------------*/
1293 if (IS_AST_SYM_VALUE(pbody->left) &&
1294 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1297 if (IS_AST_SYM_VALUE(pbody->right) &&
1298 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1301 return isConformingBody(pbody->left,sym,body) &&
1302 isConformingBody(pbody->right,sym,body);
1309 if (IS_AST_SYM_VALUE(pbody->left) &&
1310 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1312 return isConformingBody (pbody->left,sym,body);
1314 /*------------------------------------------------------------------*/
1326 case SIZEOF: /* evaluate wihout code generation */
1328 return isConformingBody(pbody->left,sym,body) &&
1329 isConformingBody(pbody->right,sym,body);
1331 /*------------------------------------------------------------------*/
1334 /* if left has a pointer & right has loop
1335 control variable then we cannot */
1336 if (astHasPointer(pbody->left) &&
1337 astHasSymbol (pbody->right,sym))
1339 if (astHasVolatile(pbody->left))
1342 if (IS_AST_SYM_VALUE(pbody->left) &&
1343 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1346 if (astHasVolatile(pbody->left))
1349 return isConformingBody(pbody->left,sym,body) &&
1350 isConformingBody(pbody->right,sym,body);
1361 assert("Parser should not have generated this\n");
1363 /*------------------------------------------------------------------*/
1364 /*----------------------------*/
1365 /* comma operator */
1366 /*----------------------------*/
1368 return isConformingBody(pbody->left,sym,body) &&
1369 isConformingBody(pbody->right,sym,body);
1371 /*------------------------------------------------------------------*/
1372 /*----------------------------*/
1374 /*----------------------------*/
1378 /*------------------------------------------------------------------*/
1379 /*----------------------------*/
1380 /* return statement */
1381 /*----------------------------*/
1386 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1391 if (astHasSymbol(pbody->left,sym))
1398 return isConformingBody(pbody->left,sym,body) &&
1399 isConformingBody(pbody->right,sym,body);
1405 /*-----------------------------------------------------------------*/
1406 /* isLoopReversible - takes a for loop as input && returns true */
1407 /* if the for loop is reversible. If yes will set the value of */
1408 /* the loop control var & init value & termination value */
1409 /*-----------------------------------------------------------------*/
1410 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1411 ast **init, ast **end )
1413 /* if option says don't do it then don't */
1414 if (optimize.noLoopReverse)
1416 /* there are several tests to determine this */
1418 /* for loop has to be of the form
1419 for ( <sym> = <const1> ;
1420 [<sym> < <const2>] ;
1421 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1423 if (! isLoopCountable (AST_FOR(loop,initExpr),
1424 AST_FOR(loop,condExpr),
1425 AST_FOR(loop,loopExpr),
1426 loopCntrl,init,end))
1429 /* now do some serious checking on the body of the loop
1432 return isConformingBody(loop->left,*loopCntrl,loop->left);
1436 /*-----------------------------------------------------------------*/
1437 /* replLoopSym - replace the loop sym by loop sym -1 */
1438 /*-----------------------------------------------------------------*/
1439 static void replLoopSym ( ast *body, symbol *sym)
1442 if (!body || IS_AST_LINK(body))
1445 if (IS_AST_SYM_VALUE(body)) {
1447 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1450 body->opval.op = '-';
1451 body->left = newAst_VALUE(symbolVal(sym));
1452 body->right= newAst_VALUE(constVal("1"));
1460 replLoopSym(body->left,sym);
1461 replLoopSym(body->right,sym);
1465 /*-----------------------------------------------------------------*/
1466 /* reverseLoop - do the actual loop reversal */
1467 /*-----------------------------------------------------------------*/
1468 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1472 /* create the following tree
1477 if (sym) goto for_continue ;
1480 /* put it together piece by piece */
1481 rloop = newNode (NULLOP,
1482 createIf(newAst_VALUE(symbolVal(sym)),
1484 newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1487 newAst_VALUE(symbolVal(sym)),
1489 newAst_VALUE(constVal("1")))));
1491 replLoopSym(loop->left, sym);
1493 rloop = newNode(NULLOP,
1495 newAst_VALUE(symbolVal(sym)),
1496 newNode('-',end,init)),
1497 createLabel(AST_FOR(loop,continueLabel),
1502 newAst_VALUE(symbolVal(sym)),
1503 newAst_VALUE(constVal("1"))),
1506 return decorateType(rloop);
1510 /*-----------------------------------------------------------------*/
1511 /* decorateType - compute type for this tree also does type cheking*/
1512 /* this is done bottom up, since type have to flow upwards*/
1513 /* it also does constant folding, and paramater checking */
1514 /*-----------------------------------------------------------------*/
1515 ast *decorateType (ast *tree)
1523 /* if already has type then do nothing */
1524 if ( tree->decorated )
1527 tree->decorated = 1;
1529 /* print the line */
1530 /* if not block & function */
1531 if ( tree->type == EX_OP &&
1532 ( tree->opval.op != FUNCTION &&
1533 tree->opval.op != BLOCK &&
1534 tree->opval.op != NULLOP )) {
1535 filename = tree->filename ;
1536 lineno = tree->lineno ;
1539 /* if any child is an error | this one is an error do nothing */
1540 if ( tree->isError ||
1541 ( tree->left && tree->left->isError) ||
1542 ( tree->right && tree->right->isError ))
1545 /*------------------------------------------------------------------*/
1546 /*----------------------------*/
1547 /* leaf has been reached */
1548 /*----------------------------*/
1549 /* if this is of type value */
1550 /* just get the type */
1551 if ( tree->type == EX_VALUE ) {
1553 if ( IS_LITERAL(tree->opval.val->etype) ) {
1555 /* if this is a character array then declare it */
1556 if (IS_ARRAY(tree->opval.val->type))
1557 tree->opval.val = stringToSymbol(tree->opval.val);
1559 /* otherwise just copy the type information */
1560 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1564 if ( tree->opval.val->sym ) {
1565 /* if the undefined flag is set then give error message */
1566 if (tree->opval.val->sym->undefined ) {
1567 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1569 TTYPE(tree) = TETYPE(tree) =
1570 tree->opval.val->type = tree->opval.val->sym->type =
1571 tree->opval.val->etype = tree->opval.val->sym->etype =
1572 copyLinkChain(INTTYPE);
1576 /* if impilicit i.e. struct/union member then no type */
1577 if (tree->opval.val->sym->implicit )
1578 TTYPE(tree) = TETYPE(tree) = NULL ;
1582 /* else copy the type */
1583 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1585 /* and mark it as referenced */
1586 tree->opval.val->sym->isref = 1;
1587 /* if this is of type function or function pointer */
1588 if (funcInChain(tree->opval.val->type)) {
1589 tree->hasVargs = tree->opval.val->sym->hasVargs;
1590 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1600 /* if type link for the case of cast */
1601 if ( tree->type == EX_LINK ) {
1602 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1609 dtl = decorateType (tree->left);
1610 dtr = decorateType (tree->right);
1612 /* this is to take care of situations
1613 when the tree gets rewritten */
1614 if (dtl != tree->left)
1616 if (dtr != tree->right)
1620 /* depending on type of operator do */
1622 switch (tree->opval.op) {
1623 /*------------------------------------------------------------------*/
1624 /*----------------------------*/
1626 /*----------------------------*/
1629 /* determine which is the array & which the index */
1630 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1632 ast *tempTree = tree->left ;
1633 tree->left = tree->right ;
1634 tree->right= tempTree ;
1637 /* first check if this is a array or a pointer */
1638 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1639 werror(E_NEED_ARRAY_PTR,"[]");
1640 goto errorTreeReturn ;
1643 /* check if the type of the idx */
1644 if (!IS_INTEGRAL(RTYPE(tree))) {
1645 werror(E_IDX_NOT_INT);
1646 goto errorTreeReturn ;
1649 /* if the left is an rvalue then error */
1651 werror(E_LVALUE_REQUIRED,"array access");
1652 goto errorTreeReturn ;
1655 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1658 /*------------------------------------------------------------------*/
1659 /*----------------------------*/
1661 /*----------------------------*/
1663 /* if this is not a structure */
1664 if (!IS_STRUCT(LTYPE(tree))) {
1665 werror(E_STRUCT_UNION,".");
1666 goto errorTreeReturn ;
1668 TTYPE(tree) = structElemType (LTYPE(tree),
1669 (tree->right->type == EX_VALUE ?
1670 tree->right->opval.val : NULL ),&tree->args);
1671 TETYPE(tree) = getSpec(TTYPE(tree));
1674 /*------------------------------------------------------------------*/
1675 /*----------------------------*/
1676 /* struct/union pointer */
1677 /*----------------------------*/
1679 /* if not pointer to a structure */
1680 if (!IS_PTR(LTYPE(tree))) {
1682 goto errorTreeReturn ;
1685 if (!IS_STRUCT(LTYPE(tree)->next)) {
1686 werror(E_STRUCT_UNION,"->");
1687 goto errorTreeReturn ;
1690 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1691 (tree->right->type == EX_VALUE ?
1692 tree->right->opval.val : NULL ),&tree->args);
1693 TETYPE(tree) = getSpec(TTYPE(tree));
1696 /*------------------------------------------------------------------*/
1697 /*----------------------------*/
1698 /* ++/-- operation */
1699 /*----------------------------*/
1700 case INC_OP: /* incerement operator unary so left only */
1703 link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1704 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1705 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1706 werror(E_CODE_WRITE,"++/--");
1715 /*------------------------------------------------------------------*/
1716 /*----------------------------*/
1718 /*----------------------------*/
1719 case '&': /* can be unary */
1720 /* if right is NULL then unary operation */
1721 if ( tree->right ) /* not an unary operation */ {
1723 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1724 werror(E_BITWISE_OP);
1725 werror(E_CONTINUE,"left & right types are ");
1726 printTypeChain(LTYPE(tree),stderr);
1727 fprintf(stderr,",");
1728 printTypeChain(RTYPE(tree),stderr);
1729 fprintf(stderr,"\n");
1730 goto errorTreeReturn ;
1733 /* if they are both literal */
1734 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1735 tree->type = EX_VALUE ;
1736 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1737 valFromType(RETYPE(tree)),'&');
1739 tree->right = tree->left = NULL;
1740 TETYPE(tree) = tree->opval.val->etype ;
1741 TTYPE(tree) = tree->opval.val->type;
1745 /* see if this is a GETHBIT operation if yes
1748 ast *otree = optimizeGetHbit(tree);
1751 return decorateType(otree);
1754 /* if right or left is literal then result of that type*/
1755 if (IS_LITERAL(RTYPE(tree))) {
1757 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1758 TETYPE(tree) = getSpec(TTYPE(tree));
1759 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1762 if (IS_LITERAL(LTYPE(tree))) {
1763 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1764 TETYPE(tree) = getSpec(TTYPE(tree));
1765 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1770 computeType (LTYPE(tree), RTYPE(tree));
1771 TETYPE(tree) = getSpec(TTYPE(tree));
1774 LRVAL(tree) = RRVAL(tree) = 1;
1778 /*------------------------------------------------------------------*/
1779 /*----------------------------*/
1781 /*----------------------------*/
1783 p->class = DECLARATOR;
1784 /* if bit field then error */
1785 if (IS_BITVAR(tree->left->etype)) {
1786 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1787 goto errorTreeReturn ;
1790 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1791 werror (E_ILLEGAL_ADDR,"address of register variable");
1792 goto errorTreeReturn;
1795 if (IS_FUNC(LTYPE(tree))) {
1796 werror(E_ILLEGAL_ADDR,"address of function");
1797 goto errorTreeReturn ;
1801 werror(E_LVALUE_REQUIRED,"address of");
1802 goto errorTreeReturn ;
1804 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1805 DCL_TYPE(p) = CPOINTER ;
1806 DCL_PTR_CONST(p) = port->mem.code_ro;
1809 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1810 DCL_TYPE(p) = FPOINTER;
1812 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1813 DCL_TYPE(p) = PPOINTER ;
1815 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1816 DCL_TYPE(p) = IPOINTER ;
1818 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1819 DCL_TYPE(p) = EEPPOINTER ;
1821 DCL_TYPE(p) = POINTER ;
1823 if (IS_AST_SYM_VALUE(tree->left)) {
1824 AST_SYMBOL(tree->left)->addrtaken = 1;
1825 AST_SYMBOL(tree->left)->allocreq = 1;
1828 p->next = LTYPE(tree);
1830 TETYPE(tree) = getSpec(TTYPE(tree));
1831 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1832 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1837 /*------------------------------------------------------------------*/
1838 /*----------------------------*/
1840 /*----------------------------*/
1842 /* if the rewrite succeeds then don't go any furthur */
1844 ast *wtree = optimizeRRCRLC ( tree );
1846 return decorateType(wtree) ;
1848 /*------------------------------------------------------------------*/
1849 /*----------------------------*/
1851 /*----------------------------*/
1853 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1854 werror(E_BITWISE_OP);
1855 werror(E_CONTINUE,"left & right types are ");
1856 printTypeChain(LTYPE(tree),stderr);
1857 fprintf(stderr,",");
1858 printTypeChain(RTYPE(tree),stderr);
1859 fprintf(stderr,"\n");
1860 goto errorTreeReturn ;
1863 /* if they are both literal then */
1864 /* rewrite the tree */
1865 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1866 tree->type = EX_VALUE ;
1867 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1868 valFromType(RETYPE(tree)),
1870 tree->right = tree->left = NULL;
1871 TETYPE(tree) = tree->opval.val->etype;
1872 TTYPE(tree) = tree->opval.val->type;
1875 LRVAL(tree) = RRVAL(tree) = 1;
1876 TETYPE(tree) = getSpec (TTYPE(tree) =
1877 computeType(LTYPE(tree),
1880 /*------------------------------------------------------------------*/
1881 /*----------------------------*/
1883 /*----------------------------*/
1885 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1886 werror(E_INVALID_OP,"divide");
1887 goto errorTreeReturn ;
1889 /* if they are both literal then */
1890 /* rewrite the tree */
1891 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1892 tree->type = EX_VALUE ;
1893 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1894 valFromType(RETYPE(tree)));
1895 tree->right = tree->left = NULL;
1896 TETYPE(tree) = getSpec(TTYPE(tree) =
1897 tree->opval.val->type);
1900 LRVAL(tree) = RRVAL(tree) = 1;
1901 TETYPE(tree) = getSpec (TTYPE(tree) =
1902 computeType(LTYPE(tree),
1906 /*------------------------------------------------------------------*/
1907 /*----------------------------*/
1909 /*----------------------------*/
1911 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1912 werror(E_BITWISE_OP);
1913 werror(E_CONTINUE,"left & right types are ");
1914 printTypeChain(LTYPE(tree),stderr);
1915 fprintf(stderr,",");
1916 printTypeChain(RTYPE(tree),stderr);
1917 fprintf(stderr,"\n");
1918 goto errorTreeReturn ;
1920 /* if they are both literal then */
1921 /* rewrite the tree */
1922 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1923 tree->type = EX_VALUE ;
1924 tree->opval.val = valMod (valFromType(LETYPE(tree)),
1925 valFromType(RETYPE(tree)));
1926 tree->right = tree->left = NULL;
1927 TETYPE(tree) = getSpec(TTYPE(tree) =
1928 tree->opval.val->type);
1931 LRVAL(tree) = RRVAL(tree) = 1;
1932 TETYPE(tree) = getSpec (TTYPE(tree) =
1933 computeType(LTYPE(tree),
1937 /*------------------------------------------------------------------*/
1938 /*----------------------------*/
1939 /* address dereference */
1940 /*----------------------------*/
1941 case '*': /* can be unary : if right is null then unary operation */
1942 if ( ! tree->right ) {
1943 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1945 goto errorTreeReturn ;
1949 werror(E_LVALUE_REQUIRED,"pointer deref");
1950 goto errorTreeReturn ;
1952 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
1953 LTYPE(tree)->next : NULL );
1954 TETYPE(tree) = getSpec(TTYPE(tree));
1955 tree->args = tree->left->args ;
1956 tree->hasVargs = tree->left->hasVargs ;
1957 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
1961 /*------------------------------------------------------------------*/
1962 /*----------------------------*/
1963 /* multiplication */
1964 /*----------------------------*/
1965 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1966 werror(E_INVALID_OP,"multiplication");
1967 goto errorTreeReturn ;
1970 /* if they are both literal then */
1971 /* rewrite the tree */
1972 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1973 tree->type = EX_VALUE ;
1974 tree->opval.val = valMult (valFromType(LETYPE(tree)),
1975 valFromType(RETYPE(tree)));
1976 tree->right = tree->left = NULL;
1977 TETYPE(tree) = getSpec(TTYPE(tree) =
1978 tree->opval.val->type);
1982 /* if left is a literal exchange left & right */
1983 if (IS_LITERAL(LTYPE(tree))) {
1984 ast *tTree = tree->left ;
1985 tree->left = tree->right ;
1986 tree->right= tTree ;
1989 LRVAL(tree) = RRVAL(tree) = 1;
1990 TETYPE(tree) = getSpec (TTYPE(tree) =
1991 computeType(LTYPE(tree),
1995 /*------------------------------------------------------------------*/
1996 /*----------------------------*/
1997 /* unary '+' operator */
1998 /*----------------------------*/
2001 if ( ! tree->right ) {
2002 if (!IS_INTEGRAL(LTYPE(tree))) {
2003 werror(E_UNARY_OP,'+');
2004 goto errorTreeReturn ;
2007 /* if left is a literal then do it */
2008 if (IS_LITERAL(LTYPE(tree))) {
2009 tree->type = EX_VALUE ;
2010 tree->opval.val = valFromType(LETYPE(tree));
2012 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2016 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2020 /*------------------------------------------------------------------*/
2021 /*----------------------------*/
2023 /*----------------------------*/
2025 /* this is not a unary operation */
2026 /* if both pointers then problem */
2027 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2028 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2029 werror(E_PTR_PLUS_PTR);
2030 goto errorTreeReturn ;
2033 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2034 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2035 werror(E_PLUS_INVALID,"+");
2036 goto errorTreeReturn ;
2039 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2040 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2041 werror(E_PLUS_INVALID,"+");
2042 goto errorTreeReturn;
2044 /* if they are both literal then */
2045 /* rewrite the tree */
2046 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2047 tree->type = EX_VALUE ;
2048 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2049 valFromType(RETYPE(tree)));
2050 tree->right = tree->left = NULL;
2051 TETYPE(tree) = getSpec(TTYPE(tree) =
2052 tree->opval.val->type);
2056 /* if the right is a pointer or left is a literal
2057 xchange left & right */
2058 if (IS_ARRAY(RTYPE(tree)) ||
2059 IS_PTR(RTYPE(tree)) ||
2060 IS_LITERAL(LTYPE(tree))) {
2061 ast *tTree = tree->left ;
2062 tree->left = tree->right ;
2063 tree->right= tTree ;
2066 LRVAL(tree) = RRVAL(tree) = 1;
2067 /* if the left is a pointer */
2068 if (IS_PTR(LTYPE(tree)))
2069 TETYPE(tree) = getSpec(TTYPE(tree) =
2072 TETYPE(tree) = getSpec(TTYPE(tree) =
2073 computeType(LTYPE(tree),
2077 /*------------------------------------------------------------------*/
2078 /*----------------------------*/
2080 /*----------------------------*/
2081 case '-' : /* can be unary */
2082 /* if right is null then unary */
2083 if ( ! tree->right ) {
2085 if (!IS_ARITHMETIC(LTYPE(tree))) {
2086 werror(E_UNARY_OP,tree->opval.op);
2087 goto errorTreeReturn ;
2090 /* if left is a literal then do it */
2091 if (IS_LITERAL(LTYPE(tree))) {
2092 tree->type = EX_VALUE ;
2093 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2095 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2099 TTYPE(tree) = LTYPE(tree);
2103 /*------------------------------------------------------------------*/
2104 /*----------------------------*/
2106 /*----------------------------*/
2108 if (!(IS_PTR(LTYPE(tree)) ||
2109 IS_ARRAY(LTYPE(tree)) ||
2110 IS_ARITHMETIC(LTYPE(tree)))) {
2111 werror(E_PLUS_INVALID,"-");
2112 goto errorTreeReturn ;
2115 if (!(IS_PTR(RTYPE(tree)) ||
2116 IS_ARRAY(RTYPE(tree)) ||
2117 IS_ARITHMETIC(RTYPE(tree)))) {
2118 werror(E_PLUS_INVALID,"-");
2119 goto errorTreeReturn ;
2122 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2123 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2124 IS_INTEGRAL(RTYPE(tree))) ) {
2125 werror(E_PLUS_INVALID,"-");
2126 goto errorTreeReturn ;
2129 /* if they are both literal then */
2130 /* rewrite the tree */
2131 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2132 tree->type = EX_VALUE ;
2133 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2134 valFromType(RETYPE(tree)));
2135 tree->right = tree->left = NULL;
2136 TETYPE(tree) = getSpec(TTYPE(tree) =
2137 tree->opval.val->type);
2141 /* if the left & right are equal then zero */
2142 if (isAstEqual(tree->left,tree->right)) {
2143 tree->type = EX_VALUE;
2144 tree->left = tree->right = NULL;
2145 tree->opval.val = constVal("0");
2146 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2150 /* if both of them are pointers or arrays then */
2151 /* the result is going to be an integer */
2152 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2153 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2154 TETYPE(tree) = TTYPE(tree) = newIntLink();
2156 /* if only the left is a pointer */
2157 /* then result is a pointer */
2158 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2159 TETYPE(tree) = getSpec(TTYPE(tree) =
2162 TETYPE(tree) = getSpec (TTYPE(tree) =
2163 computeType(LTYPE(tree),
2165 LRVAL(tree) = RRVAL(tree) = 1;
2168 /*------------------------------------------------------------------*/
2169 /*----------------------------*/
2171 /*----------------------------*/
2173 /* can be only integral type */
2174 if (!IS_INTEGRAL(LTYPE(tree))) {
2175 werror(E_UNARY_OP,tree->opval.op);
2176 goto errorTreeReturn ;
2179 /* if left is a literal then do it */
2180 if (IS_LITERAL(LTYPE(tree))) {
2181 tree->type = EX_VALUE ;
2182 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2184 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2188 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2191 /*------------------------------------------------------------------*/
2192 /*----------------------------*/
2194 /*----------------------------*/
2196 /* can be pointer */
2197 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2198 !IS_PTR(LTYPE(tree)) &&
2199 !IS_ARRAY(LTYPE(tree))) {
2200 werror(E_UNARY_OP,tree->opval.op);
2201 goto errorTreeReturn ;
2204 /* if left is a literal then do it */
2205 if (IS_LITERAL(LTYPE(tree))) {
2206 tree->type = EX_VALUE ;
2207 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2209 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2213 TTYPE(tree) = TETYPE(tree) = newCharLink();
2216 /*------------------------------------------------------------------*/
2217 /*----------------------------*/
2219 /*----------------------------*/
2222 TTYPE(tree) = LTYPE(tree);
2223 TETYPE(tree) = LETYPE(tree);
2227 TTYPE(tree) = TETYPE(tree) = newCharLink();
2232 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2233 werror(E_SHIFT_OP_INVALID);
2234 werror(E_CONTINUE,"left & right types are ");
2235 printTypeChain(LTYPE(tree),stderr);
2236 fprintf(stderr,",");
2237 printTypeChain(RTYPE(tree),stderr);
2238 fprintf(stderr,"\n");
2239 goto errorTreeReturn ;
2242 /* if they are both literal then */
2243 /* rewrite the tree */
2244 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2245 tree->type = EX_VALUE ;
2246 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2247 valFromType(RETYPE(tree)),
2248 (tree->opval.op == LEFT_OP ? 1 : 0));
2249 tree->right = tree->left = NULL;
2250 TETYPE(tree) = getSpec(TTYPE(tree) =
2251 tree->opval.val->type);
2254 /* if only the right side is a literal & we are
2255 shifting more than size of the left operand then zero */
2256 if (IS_LITERAL(RTYPE(tree)) &&
2257 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2258 (getSize(LTYPE(tree))*8)) {
2259 werror(W_SHIFT_CHANGED,
2260 (tree->opval.op == LEFT_OP ? "left" : "right"));
2261 tree->type = EX_VALUE;
2262 tree->left = tree->right = NULL;
2263 tree->opval.val = constVal("0");
2264 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2267 LRVAL(tree) = RRVAL(tree) = 1;
2268 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2269 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2271 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2275 /*------------------------------------------------------------------*/
2276 /*----------------------------*/
2278 /*----------------------------*/
2279 case CAST: /* change the type */
2280 /* cannot cast to an aggregate type */
2281 if (IS_AGGREGATE(LTYPE(tree))) {
2282 werror(E_CAST_ILLEGAL);
2283 goto errorTreeReturn ;
2286 /* if the right is a literal replace the tree */
2287 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2288 tree->type = EX_VALUE ;
2290 valCastLiteral(LTYPE(tree),
2291 floatFromVal(valFromType(RETYPE(tree))));
2294 TTYPE(tree) = tree->opval.val->type;
2297 TTYPE(tree) = LTYPE(tree);
2301 TETYPE(tree) = getSpec(TTYPE(tree));
2305 /*------------------------------------------------------------------*/
2306 /*----------------------------*/
2307 /* logical &&, || */
2308 /*----------------------------*/
2311 /* each must me arithmetic type or be a pointer */
2312 if (!IS_PTR(LTYPE(tree)) &&
2313 !IS_ARRAY(LTYPE(tree)) &&
2314 !IS_INTEGRAL(LTYPE(tree))) {
2315 werror(E_COMPARE_OP);
2316 goto errorTreeReturn ;
2319 if (!IS_PTR(RTYPE(tree)) &&
2320 !IS_ARRAY(RTYPE(tree)) &&
2321 !IS_INTEGRAL(RTYPE(tree))) {
2322 werror(E_COMPARE_OP);
2323 goto errorTreeReturn ;
2325 /* if they are both literal then */
2326 /* rewrite the tree */
2327 if (IS_LITERAL(RTYPE(tree)) &&
2328 IS_LITERAL(LTYPE(tree))) {
2329 tree->type = EX_VALUE ;
2330 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2331 valFromType(RETYPE(tree)),
2333 tree->right = tree->left = NULL;
2334 TETYPE(tree) = getSpec(TTYPE(tree) =
2335 tree->opval.val->type);
2338 LRVAL(tree) = RRVAL(tree) = 1;
2339 TTYPE(tree) = TETYPE(tree) = newCharLink();
2342 /*------------------------------------------------------------------*/
2343 /*----------------------------*/
2344 /* comparison operators */
2345 /*----------------------------*/
2353 ast *lt = optimizeCompare(tree);
2359 /* if they are pointers they must be castable */
2360 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2361 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2362 werror(E_COMPARE_OP);
2363 fprintf(stderr,"comparing type ");
2364 printTypeChain(LTYPE(tree),stderr);
2365 fprintf(stderr,"to type ");
2366 printTypeChain(RTYPE(tree),stderr);
2367 fprintf(stderr,"\n");
2368 goto errorTreeReturn ;
2371 /* else they should be promotable to one another */
2373 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2374 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2376 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2377 werror(E_COMPARE_OP);
2378 fprintf(stderr,"comparing type ");
2379 printTypeChain(LTYPE(tree),stderr);
2380 fprintf(stderr,"to type ");
2381 printTypeChain(RTYPE(tree),stderr);
2382 fprintf(stderr,"\n");
2383 goto errorTreeReturn ;
2387 /* if they are both literal then */
2388 /* rewrite the tree */
2389 if (IS_LITERAL(RTYPE(tree)) &&
2390 IS_LITERAL(LTYPE(tree))) {
2391 tree->type = EX_VALUE ;
2392 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2393 valFromType(RETYPE(tree)),
2395 tree->right = tree->left = NULL;
2396 TETYPE(tree) = getSpec(TTYPE(tree) =
2397 tree->opval.val->type);
2400 LRVAL(tree) = RRVAL(tree) = 1;
2401 TTYPE(tree) = TETYPE(tree) = newCharLink();
2404 /*------------------------------------------------------------------*/
2405 /*----------------------------*/
2407 /*----------------------------*/
2408 case SIZEOF : /* evaluate wihout code generation */
2409 /* change the type to a integer */
2410 tree->type = EX_VALUE;
2411 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2412 tree->opval.val = constVal(buffer);
2413 tree->right = tree->left = NULL;
2414 TETYPE(tree) = getSpec(TTYPE(tree) =
2415 tree->opval.val->type);
2418 /*------------------------------------------------------------------*/
2419 /*----------------------------*/
2420 /* conditional operator '?' */
2421 /*----------------------------*/
2423 /* the type is one on the left */
2424 TTYPE(tree) = LTYPE(tree);
2425 TETYPE(tree)= getSpec (TTYPE(tree));
2429 /* if they don't match we have a problem */
2430 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2431 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2432 goto errorTreeReturn ;
2435 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2436 TETYPE(tree)= getSpec(TTYPE(tree));
2440 /*------------------------------------------------------------------*/
2441 /*----------------------------*/
2442 /* assignment operators */
2443 /*----------------------------*/
2446 /* for these it must be both must be integral */
2447 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2448 !IS_ARITHMETIC(RTYPE(tree))) {
2449 werror (E_OPS_INTEGRAL);
2450 goto errorTreeReturn ;
2453 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2455 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2456 werror(E_CODE_WRITE," ");
2459 werror(E_LVALUE_REQUIRED,"*= or /=");
2460 goto errorTreeReturn ;
2470 /* for these it must be both must be integral */
2471 if (!IS_INTEGRAL(LTYPE(tree)) ||
2472 !IS_INTEGRAL(RTYPE(tree))) {
2473 werror (E_OPS_INTEGRAL);
2474 goto errorTreeReturn ;
2477 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2479 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2480 werror(E_CODE_WRITE," ");
2483 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2484 goto errorTreeReturn ;
2489 /*------------------------------------------------------------------*/
2490 /*----------------------------*/
2492 /*----------------------------*/
2494 if (!(IS_PTR(LTYPE(tree)) ||
2495 IS_ARITHMETIC(LTYPE(tree)))) {
2496 werror(E_PLUS_INVALID,"-=");
2497 goto errorTreeReturn ;
2500 if (!(IS_PTR(RTYPE(tree)) ||
2501 IS_ARITHMETIC(RTYPE(tree)))) {
2502 werror(E_PLUS_INVALID,"-=");
2503 goto errorTreeReturn ;
2506 TETYPE(tree) = getSpec (TTYPE(tree) =
2507 computeType(LTYPE(tree),
2510 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2511 werror(E_CODE_WRITE," ");
2514 werror(E_LVALUE_REQUIRED,"-=");
2515 goto errorTreeReturn ;
2520 /*------------------------------------------------------------------*/
2521 /*----------------------------*/
2523 /*----------------------------*/
2525 /* this is not a unary operation */
2526 /* if both pointers then problem */
2527 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2528 werror(E_PTR_PLUS_PTR);
2529 goto errorTreeReturn ;
2532 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2533 werror(E_PLUS_INVALID,"+=");
2534 goto errorTreeReturn ;
2537 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2538 werror(E_PLUS_INVALID,"+=");
2539 goto errorTreeReturn;
2542 TETYPE(tree) = getSpec (TTYPE(tree) =
2543 computeType(LTYPE(tree),
2546 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2547 werror(E_CODE_WRITE," ");
2550 werror(E_LVALUE_REQUIRED,"+=");
2551 goto errorTreeReturn ;
2554 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2555 tree->opval.op = '=';
2558 /*------------------------------------------------------------------*/
2559 /*----------------------------*/
2560 /* straight assignemnt */
2561 /*----------------------------*/
2563 /* cannot be an aggregate */
2564 if (IS_AGGREGATE(LTYPE(tree))) {
2565 werror(E_AGGR_ASSIGN);
2566 goto errorTreeReturn;
2569 /* they should either match or be castable */
2570 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2571 werror(E_TYPE_MISMATCH,"assignment"," ");
2572 fprintf(stderr,"type --> '");
2573 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2574 fprintf(stderr,"assigned to type --> '");
2575 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2576 goto errorTreeReturn ;
2579 /* if the left side of the tree is of type void
2580 then report error */
2581 if (IS_VOID(LTYPE(tree))) {
2582 werror(E_CAST_ZERO);
2583 fprintf(stderr,"type --> '");
2584 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2585 fprintf(stderr,"assigned to type --> '");
2586 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2589 /* extra checks for pointer types */
2590 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2591 !IS_GENPTR(LTYPE(tree))) {
2592 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2593 werror(W_PTR_ASSIGN);
2596 TETYPE(tree) = getSpec(TTYPE(tree) =
2600 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2601 werror(E_CODE_WRITE," ");
2604 werror(E_LVALUE_REQUIRED,"=");
2605 goto errorTreeReturn ;
2610 /*------------------------------------------------------------------*/
2611 /*----------------------------*/
2612 /* comma operator */
2613 /*----------------------------*/
2615 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2618 /*------------------------------------------------------------------*/
2619 /*----------------------------*/
2621 /*----------------------------*/
2626 if (processParms (tree->left,
2628 tree->right,&parmNumber))
2629 goto errorTreeReturn ;
2631 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2632 tree->left->args = reverseVal(tree->left->args);
2633 reverseParms(tree->right);
2636 tree->args = tree->left->args ;
2637 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2640 /*------------------------------------------------------------------*/
2641 /*----------------------------*/
2642 /* return statement */
2643 /*----------------------------*/
2648 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2649 werror(E_RETURN_MISMATCH);
2650 goto errorTreeReturn ;
2653 if (IS_VOID(currFunc->type->next)
2655 !IS_VOID(RTYPE(tree))) {
2656 werror(E_FUNC_VOID);
2657 goto errorTreeReturn ;
2660 /* if there is going to be a casing required then add it */
2661 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
2663 decorateType(newNode(CAST,
2664 newAst_LINK(copyLinkChain(currFunc->type->next)),
2673 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2674 werror(E_VOID_FUNC,currFunc->name);
2675 goto errorTreeReturn ;
2678 TTYPE(tree) = TETYPE(tree) = NULL ;
2681 /*------------------------------------------------------------------*/
2682 /*----------------------------*/
2683 /* switch statement */
2684 /*----------------------------*/
2686 /* the switch value must be an integer */
2687 if (!IS_INTEGRAL(LTYPE(tree))) {
2688 werror (E_SWITCH_NON_INTEGER);
2689 goto errorTreeReturn ;
2692 TTYPE(tree) = TETYPE(tree) = NULL ;
2695 /*------------------------------------------------------------------*/
2696 /*----------------------------*/
2698 /*----------------------------*/
2700 tree->left = backPatchLabels(tree->left,
2703 TTYPE(tree) = TETYPE(tree) = NULL;
2706 /*------------------------------------------------------------------*/
2707 /*----------------------------*/
2709 /*----------------------------*/
2712 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2713 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2714 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2716 /* if the for loop is reversible then
2717 reverse it otherwise do what we normally
2723 if (isLoopReversible (tree,&sym,&init,&end))
2724 return reverseLoop (tree,sym,init,end);
2726 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2727 AST_FOR(tree,continueLabel) ,
2728 AST_FOR(tree,falseLabel) ,
2729 AST_FOR(tree,condLabel) ,
2730 AST_FOR(tree,initExpr) ,
2731 AST_FOR(tree,condExpr) ,
2732 AST_FOR(tree,loopExpr),
2736 TTYPE(tree) = TETYPE(tree) = NULL ;
2740 /* some error found this tree will be killed */
2742 TTYPE(tree) = TETYPE(tree) = newCharLink();
2743 tree->opval.op = NULLOP ;
2749 /*-----------------------------------------------------------------*/
2750 /* sizeofOp - processes size of operation */
2751 /*-----------------------------------------------------------------*/
2752 value *sizeofOp( link *type)
2756 /* get the size and convert it to character */
2757 sprintf (buff,"%d", getSize(type));
2759 /* now convert into value */
2760 return constVal (buff);
2764 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2765 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2766 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2767 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2768 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2769 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2770 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2772 /*-----------------------------------------------------------------*/
2773 /* backPatchLabels - change and or not operators to flow control */
2774 /*-----------------------------------------------------------------*/
2775 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2781 if ( ! (IS_ANDORNOT(tree)))
2784 /* if this an and */
2786 static int localLbl = 0 ;
2787 symbol *localLabel ;
2789 sprintf (buffer,"_and_%d",localLbl++);
2790 localLabel = newSymbol(buffer,NestLevel);
2792 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2794 /* if left is already a IFX then just change the if true label in that */
2795 if (!IS_IFX(tree->left))
2796 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2798 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2799 /* right is a IFX then just join */
2800 if (IS_IFX(tree->right))
2801 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2803 tree->right = createLabel(localLabel,tree->right);
2804 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2806 return newNode(NULLOP,tree->left,tree->right);
2809 /* if this is an or operation */
2811 static int localLbl = 0 ;
2812 symbol *localLabel ;
2814 sprintf (buffer,"_or_%d",localLbl++);
2815 localLabel = newSymbol(buffer,NestLevel);
2817 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2819 /* if left is already a IFX then just change the if true label in that */
2820 if (!IS_IFX(tree->left))
2821 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2823 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2824 /* right is a IFX then just join */
2825 if (IS_IFX(tree->right))
2826 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2828 tree->right = createLabel(localLabel,tree->right);
2829 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2831 return newNode(NULLOP,tree->left,tree->right);
2836 int wasnot = IS_NOT(tree->left);
2837 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2839 /* if the left is already a IFX */
2840 if ( ! IS_IFX(tree->left) )
2841 tree->left = newNode (IFX,tree->left,NULL);
2844 tree->left->trueLabel = trueLabel ;
2845 tree->left->falseLabel= falseLabel ;
2847 tree->left->trueLabel = falseLabel ;
2848 tree->left->falseLabel= trueLabel ;
2854 tree->trueLabel = trueLabel ;
2855 tree->falseLabel= falseLabel;
2862 /*-----------------------------------------------------------------*/
2863 /* createBlock - create expression tree for block */
2864 /*-----------------------------------------------------------------*/
2865 ast *createBlock ( symbol *decl, ast *body )
2869 /* if the block has nothing */
2873 ex = newNode(BLOCK,NULL,body);
2874 ex->values.sym = decl ;
2876 ex->right = ex->right ;
2882 /*-----------------------------------------------------------------*/
2883 /* createLabel - creates the expression tree for labels */
2884 /*-----------------------------------------------------------------*/
2885 ast *createLabel ( symbol *label, ast *stmnt )
2888 char name[SDCC_NAME_MAX+1];
2891 /* must create fresh symbol if the symbol name */
2892 /* exists in the symbol table, since there can */
2893 /* be a variable with the same name as the labl */
2894 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2895 (csym->level == label->level))
2896 label = newSymbol(label->name,label->level);
2898 /* change the name before putting it in add _*/
2899 sprintf (name,"%s",label->name);
2901 /* put the label in the LabelSymbol table */
2902 /* but first check if a label of the same */
2904 if ( (csym = findSym(LabelTab,NULL,name)))
2905 werror(E_DUPLICATE_LABEL,label->name);
2907 addSym (LabelTab, label, name,label->level,0);
2910 label->key = labelKey++ ;
2911 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
2917 /*-----------------------------------------------------------------*/
2918 /* createCase - generates the parsetree for a case statement */
2919 /*-----------------------------------------------------------------*/
2920 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
2922 char caseLbl[SDCC_NAME_MAX+1];
2926 /* if the switch statement does not exist */
2927 /* then case is out of context */
2929 werror(E_CASE_CONTEXT);
2933 caseVal = decorateType(resolveSymbols(caseVal));
2934 /* if not a constant then error */
2935 if (!IS_LITERAL(caseVal->ftype)) {
2936 werror(E_CASE_CONSTANT);
2940 /* if not a integer than error */
2941 if (!IS_INTEGRAL(caseVal->ftype)) {
2942 werror(E_CASE_NON_INTEGER);
2946 /* find the end of the switch values chain */
2947 if (!(val = swStat->values.switchVals.swVals))
2948 swStat->values.switchVals.swVals = caseVal->opval.val ;
2950 /* also order the cases according to value */
2952 int cVal = (int) floatFromVal(caseVal->opval.val);
2953 while (val && (int) floatFromVal(val) < cVal) {
2958 /* if we reached the end then */
2960 pval->next = caseVal->opval.val;
2962 /* we found a value greater than */
2963 /* the current value we must add this */
2964 /* before the value */
2965 caseVal->opval.val->next = val;
2967 /* if this was the first in chain */
2968 if (swStat->values.switchVals.swVals == val)
2969 swStat->values.switchVals.swVals =
2972 pval->next = caseVal->opval.val;
2977 /* create the case label */
2978 sprintf(caseLbl,"_case_%d_%d",
2979 swStat->values.switchVals.swNum,
2980 (int) floatFromVal(caseVal->opval.val));
2982 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
2987 /*-----------------------------------------------------------------*/
2988 /* createDefault - creates the parse tree for the default statement*/
2989 /*-----------------------------------------------------------------*/
2990 ast *createDefault (ast *swStat, ast *stmnt)
2992 char defLbl[SDCC_NAME_MAX+1];
2994 /* if the switch statement does not exist */
2995 /* then case is out of context */
2997 werror(E_CASE_CONTEXT);
3001 /* turn on the default flag */
3002 swStat->values.switchVals.swDefault = 1 ;
3004 /* create the label */
3005 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3006 return createLabel(newSymbol(defLbl,0),stmnt);
3009 /*-----------------------------------------------------------------*/
3010 /* createIf - creates the parsetree for the if statement */
3011 /*-----------------------------------------------------------------*/
3012 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3014 static int Lblnum = 0 ;
3016 symbol *ifTrue , *ifFalse, *ifEnd ;
3018 /* if neither exists */
3019 if (! elseBody && !ifBody)
3022 /* create the labels */
3023 sprintf (buffer,"_iffalse_%d",Lblnum);
3024 ifFalse = newSymbol (buffer,NestLevel);
3025 /* if no else body then end == false */
3029 sprintf (buffer,"_ifend_%d",Lblnum);
3030 ifEnd = newSymbol (buffer,NestLevel);
3033 sprintf (buffer,"_iftrue_%d",Lblnum);
3034 ifTrue = newSymbol (buffer,NestLevel);
3038 /* attach the ifTrue label to the top of it body */
3039 ifBody = createLabel(ifTrue,ifBody);
3040 /* attach a goto end to the ifBody if else is present */
3042 ifBody = newNode(NULLOP,ifBody,
3044 newAst_VALUE(symbolVal(ifEnd)),
3046 /* put the elseLabel on the else body */
3047 elseBody = createLabel (ifFalse,elseBody);
3048 /* out the end at the end of the body */
3049 elseBody = newNode(NULLOP,
3051 createLabel(ifEnd,NULL));
3054 ifBody = newNode(NULLOP,ifBody,
3055 createLabel(ifFalse,NULL));
3057 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3058 if (IS_IFX(condAst))
3061 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3063 return newNode(NULLOP,ifTree,
3064 newNode(NULLOP,ifBody,elseBody));
3068 /*-----------------------------------------------------------------*/
3069 /* createDo - creates parse tree for do */
3072 /* _docontinue_n: */
3073 /* condition_expression +-> trueLabel -> _dobody_n */
3075 /* +-> falseLabel-> _dobreak_n */
3077 /*-----------------------------------------------------------------*/
3078 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3079 symbol *falseLabel, ast *condAst, ast *doBody )
3084 /* if the body does not exist then it is simple */
3086 condAst = backPatchLabels(condAst,continueLabel,NULL);
3087 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3088 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3089 doTree->trueLabel = continueLabel ;
3090 doTree->falseLabel= NULL ;
3094 /* otherwise we have a body */
3095 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3097 /* attach the body label to the top */
3098 doBody = createLabel(trueLabel,doBody);
3099 /* attach the continue label to end of body */
3100 doBody = newNode(NULLOP, doBody,
3101 createLabel(continueLabel,NULL));
3103 /* now put the break label at the end */
3104 if (IS_IFX(condAst))
3107 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3109 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3111 /* putting it together */
3112 return newNode(NULLOP,doBody,doTree);
3115 /*-----------------------------------------------------------------*/
3116 /* createFor - creates parse tree for 'for' statement */
3119 /* condExpr +-> trueLabel -> _forbody_n */
3121 /* +-> falseLabel-> _forbreak_n */
3124 /* _forcontinue_n: */
3126 /* goto _forcond_n ; */
3128 /*-----------------------------------------------------------------*/
3129 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3130 symbol *falseLabel,symbol *condLabel ,
3131 ast *initExpr, ast *condExpr, ast *loopExpr,
3136 /* if loopexpression not present then we can generate it */
3137 /* the same way as a while */
3139 return newNode(NULLOP,initExpr,
3140 createWhile (trueLabel, continueLabel,
3141 falseLabel,condExpr, forBody ));
3142 /* vanilla for statement */
3143 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3145 if (condExpr && !IS_IFX(condExpr))
3146 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3149 /* attach condition label to condition */
3150 condExpr = createLabel(condLabel,condExpr);
3152 /* attach body label to body */
3153 forBody = createLabel(trueLabel,forBody);
3155 /* attach continue to forLoop expression & attach */
3156 /* goto the forcond @ and of loopExpression */
3157 loopExpr = createLabel(continueLabel,
3161 newAst_VALUE(symbolVal(condLabel)),
3163 /* now start putting them together */
3164 forTree = newNode(NULLOP,initExpr,condExpr);
3165 forTree = newNode(NULLOP,forTree,forBody);
3166 forTree = newNode(NULLOP,forTree,loopExpr);
3167 /* finally add the break label */
3168 forTree = newNode(NULLOP,forTree,
3169 createLabel(falseLabel,NULL));
3173 /*-----------------------------------------------------------------*/
3174 /* createWhile - creates parse tree for while statement */
3175 /* the while statement will be created as follows */
3177 /* _while_continue_n: */
3178 /* condition_expression +-> trueLabel -> _while_boby_n */
3180 /* +-> falseLabel -> _while_break_n*/
3181 /* _while_body_n: */
3183 /* goto _while_continue_n */
3184 /* _while_break_n: */
3185 /*-----------------------------------------------------------------*/
3186 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3187 symbol *falseLabel,ast *condExpr, ast *whileBody )
3191 /* put the continue label */
3192 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3193 condExpr = createLabel(continueLabel,condExpr);
3194 condExpr->lineno = 0;
3196 /* put the body label in front of the body */
3197 whileBody = createLabel(trueLabel,whileBody);
3198 whileBody->lineno = 0;
3199 /* put a jump to continue at the end of the body */
3200 /* and put break label at the end of the body */
3201 whileBody = newNode(NULLOP,
3204 newAst_VALUE(symbolVal(continueLabel)),
3205 createLabel(falseLabel,NULL)));
3207 /* put it all together */
3208 if ( IS_IFX(condExpr) )
3209 whileTree = condExpr ;
3211 whileTree = newNode (IFX, condExpr,NULL );
3212 /* put the true & false labels in place */
3213 whileTree->trueLabel = trueLabel ;
3214 whileTree->falseLabel= falseLabel;
3217 return newNode(NULLOP,whileTree,whileBody );
3220 /*-----------------------------------------------------------------*/
3221 /* optimizeGetHbit - get highest order bit of the expression */
3222 /*-----------------------------------------------------------------*/
3223 ast *optimizeGetHbit (ast *tree)
3226 /* if this is not a bit and */
3227 if (!IS_BITAND(tree))
3230 /* will look for tree of the form
3231 ( expr >> ((sizeof expr) -1) ) & 1 */
3232 if (!IS_AST_LIT_VALUE(tree->right))
3235 if (AST_LIT_VALUE(tree->right) != 1)
3238 if (!IS_RIGHT_OP(tree->left))
3241 if (!IS_AST_LIT_VALUE(tree->left->right))
3244 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3245 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3248 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3252 /*-----------------------------------------------------------------*/
3253 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3254 /*-----------------------------------------------------------------*/
3255 ast *optimizeRRCRLC ( ast *root )
3257 /* will look for trees of the form
3258 (?expr << 1) | (?expr >> 7) or
3259 (?expr >> 7) | (?expr << 1) will make that
3260 into a RLC : operation ..
3262 (?expr >> 1) | (?expr << 7) or
3263 (?expr << 7) | (?expr >> 1) will make that
3264 into a RRC operation
3265 note : by 7 I mean (number of bits required to hold the
3267 /* if the root operations is not a | operation the not */
3268 if (!IS_BITOR(root))
3271 /* I have to think of a better way to match patterns this sucks */
3272 /* that aside let start looking for the first case : I use a the
3273 negative check a lot to improve the efficiency */
3274 /* (?expr << 1) | (?expr >> 7) */
3275 if (IS_LEFT_OP(root->left) &&
3276 IS_RIGHT_OP(root->right) ) {
3278 if (!SPEC_USIGN(TETYPE(root->left->left)))
3281 if (!IS_AST_LIT_VALUE(root->left->right) ||
3282 !IS_AST_LIT_VALUE(root->right->right))
3285 /* make sure it is the same expression */
3286 if (!isAstEqual(root->left->left,
3290 if (AST_LIT_VALUE(root->left->right) != 1 )
3293 if (AST_LIT_VALUE(root->right->right) !=
3294 (getSize(TTYPE(root->left->left))*8 - 1))
3297 /* whew got the first case : create the AST */
3298 return newNode(RLC,root->left->left,NULL);
3302 /* check for second case */
3303 /* (?expr >> 7) | (?expr << 1) */
3304 if (IS_LEFT_OP(root->right) &&
3305 IS_RIGHT_OP(root->left) ) {
3307 if (!SPEC_USIGN(TETYPE(root->left->left)))
3310 if (!IS_AST_LIT_VALUE(root->left->right) ||
3311 !IS_AST_LIT_VALUE(root->right->right))
3314 /* make sure it is the same symbol */
3315 if (!isAstEqual(root->left->left,
3319 if (AST_LIT_VALUE(root->right->right) != 1 )
3322 if (AST_LIT_VALUE(root->left->right) !=
3323 (getSize(TTYPE(root->left->left))*8 - 1))
3326 /* whew got the first case : create the AST */
3327 return newNode(RLC,root->left->left,NULL);
3332 /* third case for RRC */
3333 /* (?symbol >> 1) | (?symbol << 7) */
3334 if (IS_LEFT_OP(root->right) &&
3335 IS_RIGHT_OP(root->left) ) {
3337 if (!SPEC_USIGN(TETYPE(root->left->left)))
3340 if (!IS_AST_LIT_VALUE(root->left->right) ||
3341 !IS_AST_LIT_VALUE(root->right->right))
3344 /* make sure it is the same symbol */
3345 if (!isAstEqual(root->left->left,
3349 if (AST_LIT_VALUE(root->left->right) != 1 )
3352 if (AST_LIT_VALUE(root->right->right) !=
3353 (getSize(TTYPE(root->left->left))*8 - 1))
3356 /* whew got the first case : create the AST */
3357 return newNode(RRC,root->left->left,NULL);
3361 /* fourth and last case for now */
3362 /* (?symbol << 7) | (?symbol >> 1) */
3363 if (IS_RIGHT_OP(root->right) &&
3364 IS_LEFT_OP(root->left) ) {
3366 if (!SPEC_USIGN(TETYPE(root->left->left)))
3369 if (!IS_AST_LIT_VALUE(root->left->right) ||
3370 !IS_AST_LIT_VALUE(root->right->right))
3373 /* make sure it is the same symbol */
3374 if (!isAstEqual(root->left->left,
3378 if (AST_LIT_VALUE(root->right->right) != 1 )
3381 if (AST_LIT_VALUE(root->left->right) !=
3382 (getSize(TTYPE(root->left->left))*8 - 1))
3385 /* whew got the first case : create the AST */
3386 return newNode(RRC,root->left->left,NULL);
3390 /* not found return root */
3394 /*-----------------------------------------------------------------*/
3395 /* optimizeCompare - otimizes compares for bit variables */
3396 /*-----------------------------------------------------------------*/
3397 ast *optimizeCompare ( ast *root )
3399 ast *optExpr = NULL;
3402 unsigned int litValue ;
3404 /* if nothing then return nothing */
3408 /* if not a compare op then do leaves */
3409 if (!IS_COMPARE_OP(root)) {
3410 root->left = optimizeCompare (root->left);
3411 root->right= optimizeCompare (root->right);
3415 /* if left & right are the same then depending
3416 of the operation do */
3417 if (isAstEqual(root->left,root->right)) {
3418 switch (root->opval.op) {
3422 optExpr = newAst_VALUE(constVal("0"));
3427 optExpr = newAst_VALUE(constVal("1"));
3431 return decorateType(optExpr);
3434 vleft = (root->left->type == EX_VALUE ?
3435 root->left->opval.val : NULL );
3437 vright = (root->right->type == EX_VALUE ?
3438 root->right->opval.val : NULL);
3440 /* if left is a BITVAR in BITSPACE */
3441 /* and right is a LITERAL then opt-*/
3442 /* imize else do nothing */
3443 if (vleft && vright &&
3444 IS_BITVAR(vleft->etype) &&
3445 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3446 IS_LITERAL(vright->etype)) {
3448 /* if right side > 1 then comparison may never succeed */
3449 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3450 werror(W_BAD_COMPARE);
3455 switch (root->opval.op) {
3456 case '>' : /* bit value greater than 1 cannot be */
3457 werror(W_BAD_COMPARE);
3461 case '<' : /* bit value < 1 means 0 */
3463 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3466 case LE_OP : /* bit value <= 1 means no check */
3467 optExpr = newAst_VALUE(vright);
3470 case GE_OP : /* bit value >= 1 means only check for = */
3472 optExpr = newAst_VALUE(vleft);
3475 } else { /* literal is zero */
3476 switch (root->opval.op) {
3477 case '<' : /* bit value < 0 cannot be */
3478 werror(W_BAD_COMPARE);
3482 case '>' : /* bit value > 0 means 1 */
3484 optExpr = newAst_VALUE(vleft);
3487 case LE_OP : /* bit value <= 0 means no check */
3488 case GE_OP : /* bit value >= 0 means no check */
3489 werror(W_BAD_COMPARE);
3493 case EQ_OP : /* bit == 0 means ! of bit */
3494 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3498 return decorateType(resolveSymbols(optExpr));
3499 } /* end-of-if of BITVAR */
3504 /*-----------------------------------------------------------------*/
3505 /* addSymToBlock : adds the symbol to the first block we find */
3506 /*-----------------------------------------------------------------*/
3507 void addSymToBlock (symbol *sym, ast *tree)
3509 /* reached end of tree or a leaf */
3510 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3514 if (IS_AST_OP(tree) &&
3515 tree->opval.op == BLOCK ) {
3517 symbol *lsym = copySymbol(sym);
3519 lsym->next = AST_VALUES(tree,sym);
3520 AST_VALUES(tree,sym) = lsym ;
3524 addSymToBlock(sym,tree->left);
3525 addSymToBlock(sym,tree->right);
3528 /*-----------------------------------------------------------------*/
3529 /* processRegParms - do processing for register parameters */
3530 /*-----------------------------------------------------------------*/
3531 static void processRegParms (value *args, ast *body)
3534 if (IS_REGPARM(args->etype))
3535 addSymToBlock(args->sym,body);
3540 /*-----------------------------------------------------------------*/
3541 /* resetParmKey - resets the operandkeys for the symbols */
3542 /*-----------------------------------------------------------------*/
3543 DEFSETFUNC(resetParmKey)
3554 /*-----------------------------------------------------------------*/
3555 /* createFunction - This is the key node that calls the iCode for */
3556 /* generating the code for a function. Note code */
3557 /* is generated function by function, later when */
3558 /* add inter-procedural analysis this will change */
3559 /*-----------------------------------------------------------------*/
3560 ast *createFunction (symbol *name, ast *body )
3566 iCode *piCode = NULL;
3568 /* if check function return 0 then some problem */
3569 if (checkFunction (name) == 0)
3572 /* create a dummy block if none exists */
3574 body = newNode(BLOCK,NULL,NULL);
3578 /* check if the function name already in the symbol table */
3579 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3581 /* special case for compiler defined functions
3582 we need to add the name to the publics list : this
3583 actually means we are now compiling the compiler
3586 addSet(&publics,name);
3591 allocVariables(name);
3593 name->lastLine = yylineno;
3595 processFuncArgs(currFunc,0);
3597 /* set the stack pointer */
3598 /* PENDING: check this for the mcs51 */
3599 stackPtr = -port->stack.direction * port->stack.call_overhead;
3600 if (IS_ISR(name->etype))
3601 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3602 if (IS_RENT(name->etype) || options.stackAuto)
3603 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3605 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3607 fetype = getSpec(name->type); /* get the specifier for the function */
3608 /* if this is a reentrant function then */
3609 if (IS_RENT(fetype))
3612 allocParms (name->args); /* allocate the parameters */
3614 /* do processing for parameters that are passed in registers */
3615 processRegParms (name->args,body);
3617 /* set the stack pointer */
3621 /* allocate & autoinit the block variables */
3622 processBlockVars (body, &stack,ALLOCATE);
3624 /* save the stack information */
3625 if (options.useXstack)
3626 name->xstack = SPEC_STAK(fetype) = stack;
3628 name->stack = SPEC_STAK(fetype) = stack;
3630 /* name needs to be mangled */
3631 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3633 body = resolveSymbols(body); /* resolve the symbols */
3634 body = decorateType (body); /* propagateType & do semantic checks */
3636 ex = newAst_VALUE(symbolVal(name)); /* create name */
3637 ex = newNode (FUNCTION,ex,body);
3638 ex->values.args = name->args ;
3641 werror(E_FUNC_NO_CODE,name->name);
3645 /* create the node & generate intermediate code */
3646 codeOutFile = code->oFile;
3647 piCode = iCodeFromAst(ex);
3650 werror(E_FUNC_NO_CODE,name->name);
3654 eBBlockFromiCode(piCode);
3656 /* if there are any statics then do them */
3658 codeOutFile = statsg->oFile;
3659 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3665 /* dealloc the block variables */
3666 processBlockVars(body, &stack,DEALLOCATE);
3667 /* deallocate paramaters */
3668 deallocParms(name->args);
3670 if (IS_RENT(fetype))
3673 /* we are done freeup memory & cleanup */
3678 addSet(&operKeyReset,name);
3679 applyToSet(operKeyReset,resetParmKey);
3681 if (options.debug && !options.nodebug)
3682 cdbStructBlock(1,cdbFile);
3684 cleanUpLevel(LabelTab,0);
3685 cleanUpBlock(StructTab,1);
3686 cleanUpBlock(TypedefTab,1);
3688 xstack->syms = NULL;
3689 istack->syms = NULL;