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);
1561 if (funcInChain(tree->opval.val->type)) {
1562 tree->hasVargs = tree->opval.val->sym->hasVargs;
1563 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1568 if ( tree->opval.val->sym ) {
1569 /* if the undefined flag is set then give error message */
1570 if (tree->opval.val->sym->undefined ) {
1571 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1573 TTYPE(tree) = TETYPE(tree) =
1574 tree->opval.val->type = tree->opval.val->sym->type =
1575 tree->opval.val->etype = tree->opval.val->sym->etype =
1576 copyLinkChain(INTTYPE);
1580 /* if impilicit i.e. struct/union member then no type */
1581 if (tree->opval.val->sym->implicit )
1582 TTYPE(tree) = TETYPE(tree) = NULL ;
1586 /* else copy the type */
1587 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1589 /* and mark it as referenced */
1590 tree->opval.val->sym->isref = 1;
1591 /* if this is of type function or function pointer */
1592 if (funcInChain(tree->opval.val->type)) {
1593 tree->hasVargs = tree->opval.val->sym->hasVargs;
1594 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1604 /* if type link for the case of cast */
1605 if ( tree->type == EX_LINK ) {
1606 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1613 dtl = decorateType (tree->left);
1614 dtr = decorateType (tree->right);
1616 /* this is to take care of situations
1617 when the tree gets rewritten */
1618 if (dtl != tree->left)
1620 if (dtr != tree->right)
1624 /* depending on type of operator do */
1626 switch (tree->opval.op) {
1627 /*------------------------------------------------------------------*/
1628 /*----------------------------*/
1630 /*----------------------------*/
1633 /* determine which is the array & which the index */
1634 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1636 ast *tempTree = tree->left ;
1637 tree->left = tree->right ;
1638 tree->right= tempTree ;
1641 /* first check if this is a array or a pointer */
1642 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1643 werror(E_NEED_ARRAY_PTR,"[]");
1644 goto errorTreeReturn ;
1647 /* check if the type of the idx */
1648 if (!IS_INTEGRAL(RTYPE(tree))) {
1649 werror(E_IDX_NOT_INT);
1650 goto errorTreeReturn ;
1653 /* if the left is an rvalue then error */
1655 werror(E_LVALUE_REQUIRED,"array access");
1656 goto errorTreeReturn ;
1659 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1662 /*------------------------------------------------------------------*/
1663 /*----------------------------*/
1665 /*----------------------------*/
1667 /* if this is not a structure */
1668 if (!IS_STRUCT(LTYPE(tree))) {
1669 werror(E_STRUCT_UNION,".");
1670 goto errorTreeReturn ;
1672 TTYPE(tree) = structElemType (LTYPE(tree),
1673 (tree->right->type == EX_VALUE ?
1674 tree->right->opval.val : NULL ),&tree->args);
1675 TETYPE(tree) = getSpec(TTYPE(tree));
1678 /*------------------------------------------------------------------*/
1679 /*----------------------------*/
1680 /* struct/union pointer */
1681 /*----------------------------*/
1683 /* if not pointer to a structure */
1684 if (!IS_PTR(LTYPE(tree))) {
1686 goto errorTreeReturn ;
1689 if (!IS_STRUCT(LTYPE(tree)->next)) {
1690 werror(E_STRUCT_UNION,"->");
1691 goto errorTreeReturn ;
1694 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1695 (tree->right->type == EX_VALUE ?
1696 tree->right->opval.val : NULL ),&tree->args);
1697 TETYPE(tree) = getSpec(TTYPE(tree));
1700 /*------------------------------------------------------------------*/
1701 /*----------------------------*/
1702 /* ++/-- operation */
1703 /*----------------------------*/
1704 case INC_OP: /* incerement operator unary so left only */
1707 link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1708 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1709 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1710 werror(E_CODE_WRITE,"++/--");
1719 /*------------------------------------------------------------------*/
1720 /*----------------------------*/
1722 /*----------------------------*/
1723 case '&': /* can be unary */
1724 /* if right is NULL then unary operation */
1725 if ( tree->right ) /* not an unary operation */ {
1727 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1728 werror(E_BITWISE_OP);
1729 werror(E_CONTINUE,"left & right types are ");
1730 printTypeChain(LTYPE(tree),stderr);
1731 fprintf(stderr,",");
1732 printTypeChain(RTYPE(tree),stderr);
1733 fprintf(stderr,"\n");
1734 goto errorTreeReturn ;
1737 /* if they are both literal */
1738 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1739 tree->type = EX_VALUE ;
1740 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1741 valFromType(RETYPE(tree)),'&');
1743 tree->right = tree->left = NULL;
1744 TETYPE(tree) = tree->opval.val->etype ;
1745 TTYPE(tree) = tree->opval.val->type;
1749 /* see if this is a GETHBIT operation if yes
1752 ast *otree = optimizeGetHbit(tree);
1755 return decorateType(otree);
1758 /* if right or left is literal then result of that type*/
1759 if (IS_LITERAL(RTYPE(tree))) {
1761 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1762 TETYPE(tree) = getSpec(TTYPE(tree));
1763 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1766 if (IS_LITERAL(LTYPE(tree))) {
1767 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1768 TETYPE(tree) = getSpec(TTYPE(tree));
1769 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1774 computeType (LTYPE(tree), RTYPE(tree));
1775 TETYPE(tree) = getSpec(TTYPE(tree));
1778 LRVAL(tree) = RRVAL(tree) = 1;
1782 /*------------------------------------------------------------------*/
1783 /*----------------------------*/
1785 /*----------------------------*/
1787 p->class = DECLARATOR;
1788 /* if bit field then error */
1789 if (IS_BITVAR(tree->left->etype)) {
1790 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1791 goto errorTreeReturn ;
1794 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1795 werror (E_ILLEGAL_ADDR,"address of register variable");
1796 goto errorTreeReturn;
1799 if (IS_FUNC(LTYPE(tree))) {
1800 werror(E_ILLEGAL_ADDR,"address of function");
1801 goto errorTreeReturn ;
1805 werror(E_LVALUE_REQUIRED,"address of");
1806 goto errorTreeReturn ;
1808 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1809 DCL_TYPE(p) = CPOINTER ;
1810 DCL_PTR_CONST(p) = port->mem.code_ro;
1813 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1814 DCL_TYPE(p) = FPOINTER;
1816 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1817 DCL_TYPE(p) = PPOINTER ;
1819 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1820 DCL_TYPE(p) = IPOINTER ;
1822 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1823 DCL_TYPE(p) = EEPPOINTER ;
1825 DCL_TYPE(p) = POINTER ;
1827 if (IS_AST_SYM_VALUE(tree->left)) {
1828 AST_SYMBOL(tree->left)->addrtaken = 1;
1829 AST_SYMBOL(tree->left)->allocreq = 1;
1832 p->next = LTYPE(tree);
1834 TETYPE(tree) = getSpec(TTYPE(tree));
1835 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1836 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1841 /*------------------------------------------------------------------*/
1842 /*----------------------------*/
1844 /*----------------------------*/
1846 /* if the rewrite succeeds then don't go any furthur */
1848 ast *wtree = optimizeRRCRLC ( tree );
1850 return decorateType(wtree) ;
1852 /*------------------------------------------------------------------*/
1853 /*----------------------------*/
1855 /*----------------------------*/
1857 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1858 werror(E_BITWISE_OP);
1859 werror(E_CONTINUE,"left & right types are ");
1860 printTypeChain(LTYPE(tree),stderr);
1861 fprintf(stderr,",");
1862 printTypeChain(RTYPE(tree),stderr);
1863 fprintf(stderr,"\n");
1864 goto errorTreeReturn ;
1867 /* if they are both literal then */
1868 /* rewrite the tree */
1869 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1870 tree->type = EX_VALUE ;
1871 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1872 valFromType(RETYPE(tree)),
1874 tree->right = tree->left = NULL;
1875 TETYPE(tree) = tree->opval.val->etype;
1876 TTYPE(tree) = tree->opval.val->type;
1879 LRVAL(tree) = RRVAL(tree) = 1;
1880 TETYPE(tree) = getSpec (TTYPE(tree) =
1881 computeType(LTYPE(tree),
1884 /*------------------------------------------------------------------*/
1885 /*----------------------------*/
1887 /*----------------------------*/
1889 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1890 werror(E_INVALID_OP,"divide");
1891 goto errorTreeReturn ;
1893 /* if they are both literal then */
1894 /* rewrite the tree */
1895 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1896 tree->type = EX_VALUE ;
1897 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1898 valFromType(RETYPE(tree)));
1899 tree->right = tree->left = NULL;
1900 TETYPE(tree) = getSpec(TTYPE(tree) =
1901 tree->opval.val->type);
1904 LRVAL(tree) = RRVAL(tree) = 1;
1905 TETYPE(tree) = getSpec (TTYPE(tree) =
1906 computeType(LTYPE(tree),
1910 /*------------------------------------------------------------------*/
1911 /*----------------------------*/
1913 /*----------------------------*/
1915 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1916 werror(E_BITWISE_OP);
1917 werror(E_CONTINUE,"left & right types are ");
1918 printTypeChain(LTYPE(tree),stderr);
1919 fprintf(stderr,",");
1920 printTypeChain(RTYPE(tree),stderr);
1921 fprintf(stderr,"\n");
1922 goto errorTreeReturn ;
1924 /* if they are both literal then */
1925 /* rewrite the tree */
1926 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1927 tree->type = EX_VALUE ;
1928 tree->opval.val = valMod (valFromType(LETYPE(tree)),
1929 valFromType(RETYPE(tree)));
1930 tree->right = tree->left = NULL;
1931 TETYPE(tree) = getSpec(TTYPE(tree) =
1932 tree->opval.val->type);
1935 LRVAL(tree) = RRVAL(tree) = 1;
1936 TETYPE(tree) = getSpec (TTYPE(tree) =
1937 computeType(LTYPE(tree),
1941 /*------------------------------------------------------------------*/
1942 /*----------------------------*/
1943 /* address dereference */
1944 /*----------------------------*/
1945 case '*': /* can be unary : if right is null then unary operation */
1946 if ( ! tree->right ) {
1947 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1949 goto errorTreeReturn ;
1953 werror(E_LVALUE_REQUIRED,"pointer deref");
1954 goto errorTreeReturn ;
1956 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
1957 LTYPE(tree)->next : NULL );
1958 TETYPE(tree) = getSpec(TTYPE(tree));
1959 tree->args = tree->left->args ;
1960 tree->hasVargs = tree->left->hasVargs ;
1961 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
1965 /*------------------------------------------------------------------*/
1966 /*----------------------------*/
1967 /* multiplication */
1968 /*----------------------------*/
1969 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1970 werror(E_INVALID_OP,"multiplication");
1971 goto errorTreeReturn ;
1974 /* if they are both literal then */
1975 /* rewrite the tree */
1976 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1977 tree->type = EX_VALUE ;
1978 tree->opval.val = valMult (valFromType(LETYPE(tree)),
1979 valFromType(RETYPE(tree)));
1980 tree->right = tree->left = NULL;
1981 TETYPE(tree) = getSpec(TTYPE(tree) =
1982 tree->opval.val->type);
1986 /* if left is a literal exchange left & right */
1987 if (IS_LITERAL(LTYPE(tree))) {
1988 ast *tTree = tree->left ;
1989 tree->left = tree->right ;
1990 tree->right= tTree ;
1993 LRVAL(tree) = RRVAL(tree) = 1;
1994 TETYPE(tree) = getSpec (TTYPE(tree) =
1995 computeType(LTYPE(tree),
1999 /*------------------------------------------------------------------*/
2000 /*----------------------------*/
2001 /* unary '+' operator */
2002 /*----------------------------*/
2005 if ( ! tree->right ) {
2006 if (!IS_INTEGRAL(LTYPE(tree))) {
2007 werror(E_UNARY_OP,'+');
2008 goto errorTreeReturn ;
2011 /* if left is a literal then do it */
2012 if (IS_LITERAL(LTYPE(tree))) {
2013 tree->type = EX_VALUE ;
2014 tree->opval.val = valFromType(LETYPE(tree));
2016 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2020 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2024 /*------------------------------------------------------------------*/
2025 /*----------------------------*/
2027 /*----------------------------*/
2029 /* this is not a unary operation */
2030 /* if both pointers then problem */
2031 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2032 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2033 werror(E_PTR_PLUS_PTR);
2034 goto errorTreeReturn ;
2037 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2038 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2039 werror(E_PLUS_INVALID,"+");
2040 goto errorTreeReturn ;
2043 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2044 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2045 werror(E_PLUS_INVALID,"+");
2046 goto errorTreeReturn;
2048 /* if they are both literal then */
2049 /* rewrite the tree */
2050 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2051 tree->type = EX_VALUE ;
2052 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2053 valFromType(RETYPE(tree)));
2054 tree->right = tree->left = NULL;
2055 TETYPE(tree) = getSpec(TTYPE(tree) =
2056 tree->opval.val->type);
2060 /* if the right is a pointer or left is a literal
2061 xchange left & right */
2062 if (IS_ARRAY(RTYPE(tree)) ||
2063 IS_PTR(RTYPE(tree)) ||
2064 IS_LITERAL(LTYPE(tree))) {
2065 ast *tTree = tree->left ;
2066 tree->left = tree->right ;
2067 tree->right= tTree ;
2070 LRVAL(tree) = RRVAL(tree) = 1;
2071 /* if the left is a pointer */
2072 if (IS_PTR(LTYPE(tree)))
2073 TETYPE(tree) = getSpec(TTYPE(tree) =
2076 TETYPE(tree) = getSpec(TTYPE(tree) =
2077 computeType(LTYPE(tree),
2081 /*------------------------------------------------------------------*/
2082 /*----------------------------*/
2084 /*----------------------------*/
2085 case '-' : /* can be unary */
2086 /* if right is null then unary */
2087 if ( ! tree->right ) {
2089 if (!IS_ARITHMETIC(LTYPE(tree))) {
2090 werror(E_UNARY_OP,tree->opval.op);
2091 goto errorTreeReturn ;
2094 /* if left is a literal then do it */
2095 if (IS_LITERAL(LTYPE(tree))) {
2096 tree->type = EX_VALUE ;
2097 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2099 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2103 TTYPE(tree) = LTYPE(tree);
2107 /*------------------------------------------------------------------*/
2108 /*----------------------------*/
2110 /*----------------------------*/
2112 if (!(IS_PTR(LTYPE(tree)) ||
2113 IS_ARRAY(LTYPE(tree)) ||
2114 IS_ARITHMETIC(LTYPE(tree)))) {
2115 werror(E_PLUS_INVALID,"-");
2116 goto errorTreeReturn ;
2119 if (!(IS_PTR(RTYPE(tree)) ||
2120 IS_ARRAY(RTYPE(tree)) ||
2121 IS_ARITHMETIC(RTYPE(tree)))) {
2122 werror(E_PLUS_INVALID,"-");
2123 goto errorTreeReturn ;
2126 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2127 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2128 IS_INTEGRAL(RTYPE(tree))) ) {
2129 werror(E_PLUS_INVALID,"-");
2130 goto errorTreeReturn ;
2133 /* if they are both literal then */
2134 /* rewrite the tree */
2135 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2136 tree->type = EX_VALUE ;
2137 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2138 valFromType(RETYPE(tree)));
2139 tree->right = tree->left = NULL;
2140 TETYPE(tree) = getSpec(TTYPE(tree) =
2141 tree->opval.val->type);
2145 /* if the left & right are equal then zero */
2146 if (isAstEqual(tree->left,tree->right)) {
2147 tree->type = EX_VALUE;
2148 tree->left = tree->right = NULL;
2149 tree->opval.val = constVal("0");
2150 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2154 /* if both of them are pointers or arrays then */
2155 /* the result is going to be an integer */
2156 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2157 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2158 TETYPE(tree) = TTYPE(tree) = newIntLink();
2160 /* if only the left is a pointer */
2161 /* then result is a pointer */
2162 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2163 TETYPE(tree) = getSpec(TTYPE(tree) =
2166 TETYPE(tree) = getSpec (TTYPE(tree) =
2167 computeType(LTYPE(tree),
2169 LRVAL(tree) = RRVAL(tree) = 1;
2172 /*------------------------------------------------------------------*/
2173 /*----------------------------*/
2175 /*----------------------------*/
2177 /* can be only integral type */
2178 if (!IS_INTEGRAL(LTYPE(tree))) {
2179 werror(E_UNARY_OP,tree->opval.op);
2180 goto errorTreeReturn ;
2183 /* if left is a literal then do it */
2184 if (IS_LITERAL(LTYPE(tree))) {
2185 tree->type = EX_VALUE ;
2186 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2188 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2192 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2195 /*------------------------------------------------------------------*/
2196 /*----------------------------*/
2198 /*----------------------------*/
2200 /* can be pointer */
2201 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2202 !IS_PTR(LTYPE(tree)) &&
2203 !IS_ARRAY(LTYPE(tree))) {
2204 werror(E_UNARY_OP,tree->opval.op);
2205 goto errorTreeReturn ;
2208 /* if left is a literal then do it */
2209 if (IS_LITERAL(LTYPE(tree))) {
2210 tree->type = EX_VALUE ;
2211 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2213 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2217 TTYPE(tree) = TETYPE(tree) = newCharLink();
2220 /*------------------------------------------------------------------*/
2221 /*----------------------------*/
2223 /*----------------------------*/
2226 TTYPE(tree) = LTYPE(tree);
2227 TETYPE(tree) = LETYPE(tree);
2231 TTYPE(tree) = TETYPE(tree) = newCharLink();
2236 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2237 werror(E_SHIFT_OP_INVALID);
2238 werror(E_CONTINUE,"left & right types are ");
2239 printTypeChain(LTYPE(tree),stderr);
2240 fprintf(stderr,",");
2241 printTypeChain(RTYPE(tree),stderr);
2242 fprintf(stderr,"\n");
2243 goto errorTreeReturn ;
2246 /* if they are both literal then */
2247 /* rewrite the tree */
2248 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2249 tree->type = EX_VALUE ;
2250 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2251 valFromType(RETYPE(tree)),
2252 (tree->opval.op == LEFT_OP ? 1 : 0));
2253 tree->right = tree->left = NULL;
2254 TETYPE(tree) = getSpec(TTYPE(tree) =
2255 tree->opval.val->type);
2258 /* if only the right side is a literal & we are
2259 shifting more than size of the left operand then zero */
2260 if (IS_LITERAL(RTYPE(tree)) &&
2261 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2262 (getSize(LTYPE(tree))*8)) {
2263 werror(W_SHIFT_CHANGED,
2264 (tree->opval.op == LEFT_OP ? "left" : "right"));
2265 tree->type = EX_VALUE;
2266 tree->left = tree->right = NULL;
2267 tree->opval.val = constVal("0");
2268 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2271 LRVAL(tree) = RRVAL(tree) = 1;
2272 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2273 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2275 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2279 /*------------------------------------------------------------------*/
2280 /*----------------------------*/
2282 /*----------------------------*/
2283 case CAST: /* change the type */
2284 /* cannot cast to an aggregate type */
2285 if (IS_AGGREGATE(LTYPE(tree))) {
2286 werror(E_CAST_ILLEGAL);
2287 goto errorTreeReturn ;
2290 /* if the right is a literal replace the tree */
2291 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2292 tree->type = EX_VALUE ;
2294 valCastLiteral(LTYPE(tree),
2295 floatFromVal(valFromType(RETYPE(tree))));
2298 TTYPE(tree) = tree->opval.val->type;
2301 TTYPE(tree) = LTYPE(tree);
2305 TETYPE(tree) = getSpec(TTYPE(tree));
2309 /*------------------------------------------------------------------*/
2310 /*----------------------------*/
2311 /* logical &&, || */
2312 /*----------------------------*/
2315 /* each must me arithmetic type or be a pointer */
2316 if (!IS_PTR(LTYPE(tree)) &&
2317 !IS_ARRAY(LTYPE(tree)) &&
2318 !IS_INTEGRAL(LTYPE(tree))) {
2319 werror(E_COMPARE_OP);
2320 goto errorTreeReturn ;
2323 if (!IS_PTR(RTYPE(tree)) &&
2324 !IS_ARRAY(RTYPE(tree)) &&
2325 !IS_INTEGRAL(RTYPE(tree))) {
2326 werror(E_COMPARE_OP);
2327 goto errorTreeReturn ;
2329 /* if they are both literal then */
2330 /* rewrite the tree */
2331 if (IS_LITERAL(RTYPE(tree)) &&
2332 IS_LITERAL(LTYPE(tree))) {
2333 tree->type = EX_VALUE ;
2334 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2335 valFromType(RETYPE(tree)),
2337 tree->right = tree->left = NULL;
2338 TETYPE(tree) = getSpec(TTYPE(tree) =
2339 tree->opval.val->type);
2342 LRVAL(tree) = RRVAL(tree) = 1;
2343 TTYPE(tree) = TETYPE(tree) = newCharLink();
2346 /*------------------------------------------------------------------*/
2347 /*----------------------------*/
2348 /* comparison operators */
2349 /*----------------------------*/
2357 ast *lt = optimizeCompare(tree);
2363 /* if they are pointers they must be castable */
2364 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2365 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2366 werror(E_COMPARE_OP);
2367 fprintf(stderr,"comparing type ");
2368 printTypeChain(LTYPE(tree),stderr);
2369 fprintf(stderr,"to type ");
2370 printTypeChain(RTYPE(tree),stderr);
2371 fprintf(stderr,"\n");
2372 goto errorTreeReturn ;
2375 /* else they should be promotable to one another */
2377 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2378 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2380 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2381 werror(E_COMPARE_OP);
2382 fprintf(stderr,"comparing type ");
2383 printTypeChain(LTYPE(tree),stderr);
2384 fprintf(stderr,"to type ");
2385 printTypeChain(RTYPE(tree),stderr);
2386 fprintf(stderr,"\n");
2387 goto errorTreeReturn ;
2391 /* if they are both literal then */
2392 /* rewrite the tree */
2393 if (IS_LITERAL(RTYPE(tree)) &&
2394 IS_LITERAL(LTYPE(tree))) {
2395 tree->type = EX_VALUE ;
2396 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2397 valFromType(RETYPE(tree)),
2399 tree->right = tree->left = NULL;
2400 TETYPE(tree) = getSpec(TTYPE(tree) =
2401 tree->opval.val->type);
2404 LRVAL(tree) = RRVAL(tree) = 1;
2405 TTYPE(tree) = TETYPE(tree) = newCharLink();
2408 /*------------------------------------------------------------------*/
2409 /*----------------------------*/
2411 /*----------------------------*/
2412 case SIZEOF : /* evaluate wihout code generation */
2413 /* change the type to a integer */
2414 tree->type = EX_VALUE;
2415 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2416 tree->opval.val = constVal(buffer);
2417 tree->right = tree->left = NULL;
2418 TETYPE(tree) = getSpec(TTYPE(tree) =
2419 tree->opval.val->type);
2422 /*------------------------------------------------------------------*/
2423 /*----------------------------*/
2424 /* conditional operator '?' */
2425 /*----------------------------*/
2427 /* the type is one on the left */
2428 TTYPE(tree) = LTYPE(tree);
2429 TETYPE(tree)= getSpec (TTYPE(tree));
2433 /* if they don't match we have a problem */
2434 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2435 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2436 goto errorTreeReturn ;
2439 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2440 TETYPE(tree)= getSpec(TTYPE(tree));
2444 /*------------------------------------------------------------------*/
2445 /*----------------------------*/
2446 /* assignment operators */
2447 /*----------------------------*/
2450 /* for these it must be both must be integral */
2451 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2452 !IS_ARITHMETIC(RTYPE(tree))) {
2453 werror (E_OPS_INTEGRAL);
2454 goto errorTreeReturn ;
2457 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2459 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2460 werror(E_CODE_WRITE," ");
2463 werror(E_LVALUE_REQUIRED,"*= or /=");
2464 goto errorTreeReturn ;
2474 /* for these it must be both must be integral */
2475 if (!IS_INTEGRAL(LTYPE(tree)) ||
2476 !IS_INTEGRAL(RTYPE(tree))) {
2477 werror (E_OPS_INTEGRAL);
2478 goto errorTreeReturn ;
2481 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2483 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2484 werror(E_CODE_WRITE," ");
2487 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2488 goto errorTreeReturn ;
2493 /*------------------------------------------------------------------*/
2494 /*----------------------------*/
2496 /*----------------------------*/
2498 if (!(IS_PTR(LTYPE(tree)) ||
2499 IS_ARITHMETIC(LTYPE(tree)))) {
2500 werror(E_PLUS_INVALID,"-=");
2501 goto errorTreeReturn ;
2504 if (!(IS_PTR(RTYPE(tree)) ||
2505 IS_ARITHMETIC(RTYPE(tree)))) {
2506 werror(E_PLUS_INVALID,"-=");
2507 goto errorTreeReturn ;
2510 TETYPE(tree) = getSpec (TTYPE(tree) =
2511 computeType(LTYPE(tree),
2514 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2515 werror(E_CODE_WRITE," ");
2518 werror(E_LVALUE_REQUIRED,"-=");
2519 goto errorTreeReturn ;
2524 /*------------------------------------------------------------------*/
2525 /*----------------------------*/
2527 /*----------------------------*/
2529 /* this is not a unary operation */
2530 /* if both pointers then problem */
2531 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2532 werror(E_PTR_PLUS_PTR);
2533 goto errorTreeReturn ;
2536 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2537 werror(E_PLUS_INVALID,"+=");
2538 goto errorTreeReturn ;
2541 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2542 werror(E_PLUS_INVALID,"+=");
2543 goto errorTreeReturn;
2546 TETYPE(tree) = getSpec (TTYPE(tree) =
2547 computeType(LTYPE(tree),
2550 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2551 werror(E_CODE_WRITE," ");
2554 werror(E_LVALUE_REQUIRED,"+=");
2555 goto errorTreeReturn ;
2558 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2559 tree->opval.op = '=';
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2564 /* straight assignemnt */
2565 /*----------------------------*/
2567 /* cannot be an aggregate */
2568 if (IS_AGGREGATE(LTYPE(tree))) {
2569 werror(E_AGGR_ASSIGN);
2570 goto errorTreeReturn;
2573 /* they should either match or be castable */
2574 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2575 werror(E_TYPE_MISMATCH,"assignment"," ");
2576 fprintf(stderr,"type --> '");
2577 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2578 fprintf(stderr,"assigned to type --> '");
2579 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2580 goto errorTreeReturn ;
2583 /* if the left side of the tree is of type void
2584 then report error */
2585 if (IS_VOID(LTYPE(tree))) {
2586 werror(E_CAST_ZERO);
2587 fprintf(stderr,"type --> '");
2588 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2589 fprintf(stderr,"assigned to type --> '");
2590 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2593 /* extra checks for pointer types */
2594 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2595 !IS_GENPTR(LTYPE(tree))) {
2596 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2597 werror(W_PTR_ASSIGN);
2600 TETYPE(tree) = getSpec(TTYPE(tree) =
2604 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2605 werror(E_CODE_WRITE," ");
2608 werror(E_LVALUE_REQUIRED,"=");
2609 goto errorTreeReturn ;
2614 /*------------------------------------------------------------------*/
2615 /*----------------------------*/
2616 /* comma operator */
2617 /*----------------------------*/
2619 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2622 /*------------------------------------------------------------------*/
2623 /*----------------------------*/
2625 /*----------------------------*/
2630 if (processParms (tree->left,
2632 tree->right,&parmNumber))
2633 goto errorTreeReturn ;
2635 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2636 tree->left->args = reverseVal(tree->left->args);
2637 reverseParms(tree->right);
2640 tree->args = tree->left->args ;
2641 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2644 /*------------------------------------------------------------------*/
2645 /*----------------------------*/
2646 /* return statement */
2647 /*----------------------------*/
2652 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2653 werror(E_RETURN_MISMATCH);
2654 goto errorTreeReturn ;
2657 if (IS_VOID(currFunc->type->next)
2659 !IS_VOID(RTYPE(tree))) {
2660 werror(E_FUNC_VOID);
2661 goto errorTreeReturn ;
2664 /* if there is going to be a casing required then add it */
2665 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
2667 decorateType(newNode(CAST,
2668 newAst_LINK(copyLinkChain(currFunc->type->next)),
2677 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2678 werror(E_VOID_FUNC,currFunc->name);
2679 goto errorTreeReturn ;
2682 TTYPE(tree) = TETYPE(tree) = NULL ;
2685 /*------------------------------------------------------------------*/
2686 /*----------------------------*/
2687 /* switch statement */
2688 /*----------------------------*/
2690 /* the switch value must be an integer */
2691 if (!IS_INTEGRAL(LTYPE(tree))) {
2692 werror (E_SWITCH_NON_INTEGER);
2693 goto errorTreeReturn ;
2696 TTYPE(tree) = TETYPE(tree) = NULL ;
2699 /*------------------------------------------------------------------*/
2700 /*----------------------------*/
2702 /*----------------------------*/
2704 tree->left = backPatchLabels(tree->left,
2707 TTYPE(tree) = TETYPE(tree) = NULL;
2710 /*------------------------------------------------------------------*/
2711 /*----------------------------*/
2713 /*----------------------------*/
2716 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2717 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2718 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2720 /* if the for loop is reversible then
2721 reverse it otherwise do what we normally
2727 if (isLoopReversible (tree,&sym,&init,&end))
2728 return reverseLoop (tree,sym,init,end);
2730 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2731 AST_FOR(tree,continueLabel) ,
2732 AST_FOR(tree,falseLabel) ,
2733 AST_FOR(tree,condLabel) ,
2734 AST_FOR(tree,initExpr) ,
2735 AST_FOR(tree,condExpr) ,
2736 AST_FOR(tree,loopExpr),
2740 TTYPE(tree) = TETYPE(tree) = NULL ;
2744 /* some error found this tree will be killed */
2746 TTYPE(tree) = TETYPE(tree) = newCharLink();
2747 tree->opval.op = NULLOP ;
2753 /*-----------------------------------------------------------------*/
2754 /* sizeofOp - processes size of operation */
2755 /*-----------------------------------------------------------------*/
2756 value *sizeofOp( link *type)
2760 /* get the size and convert it to character */
2761 sprintf (buff,"%d", getSize(type));
2763 /* now convert into value */
2764 return constVal (buff);
2768 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2769 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2770 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2771 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2772 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2773 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2774 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2776 /*-----------------------------------------------------------------*/
2777 /* backPatchLabels - change and or not operators to flow control */
2778 /*-----------------------------------------------------------------*/
2779 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2785 if ( ! (IS_ANDORNOT(tree)))
2788 /* if this an and */
2790 static int localLbl = 0 ;
2791 symbol *localLabel ;
2793 sprintf (buffer,"_and_%d",localLbl++);
2794 localLabel = newSymbol(buffer,NestLevel);
2796 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2798 /* if left is already a IFX then just change the if true label in that */
2799 if (!IS_IFX(tree->left))
2800 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2802 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2803 /* right is a IFX then just join */
2804 if (IS_IFX(tree->right))
2805 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2807 tree->right = createLabel(localLabel,tree->right);
2808 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2810 return newNode(NULLOP,tree->left,tree->right);
2813 /* if this is an or operation */
2815 static int localLbl = 0 ;
2816 symbol *localLabel ;
2818 sprintf (buffer,"_or_%d",localLbl++);
2819 localLabel = newSymbol(buffer,NestLevel);
2821 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2823 /* if left is already a IFX then just change the if true label in that */
2824 if (!IS_IFX(tree->left))
2825 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2827 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2828 /* right is a IFX then just join */
2829 if (IS_IFX(tree->right))
2830 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2832 tree->right = createLabel(localLabel,tree->right);
2833 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2835 return newNode(NULLOP,tree->left,tree->right);
2840 int wasnot = IS_NOT(tree->left);
2841 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2843 /* if the left is already a IFX */
2844 if ( ! IS_IFX(tree->left) )
2845 tree->left = newNode (IFX,tree->left,NULL);
2848 tree->left->trueLabel = trueLabel ;
2849 tree->left->falseLabel= falseLabel ;
2851 tree->left->trueLabel = falseLabel ;
2852 tree->left->falseLabel= trueLabel ;
2858 tree->trueLabel = trueLabel ;
2859 tree->falseLabel= falseLabel;
2866 /*-----------------------------------------------------------------*/
2867 /* createBlock - create expression tree for block */
2868 /*-----------------------------------------------------------------*/
2869 ast *createBlock ( symbol *decl, ast *body )
2873 /* if the block has nothing */
2877 ex = newNode(BLOCK,NULL,body);
2878 ex->values.sym = decl ;
2880 ex->right = ex->right ;
2886 /*-----------------------------------------------------------------*/
2887 /* createLabel - creates the expression tree for labels */
2888 /*-----------------------------------------------------------------*/
2889 ast *createLabel ( symbol *label, ast *stmnt )
2892 char name[SDCC_NAME_MAX+1];
2895 /* must create fresh symbol if the symbol name */
2896 /* exists in the symbol table, since there can */
2897 /* be a variable with the same name as the labl */
2898 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2899 (csym->level == label->level))
2900 label = newSymbol(label->name,label->level);
2902 /* change the name before putting it in add _*/
2903 sprintf (name,"%s",label->name);
2905 /* put the label in the LabelSymbol table */
2906 /* but first check if a label of the same */
2908 if ( (csym = findSym(LabelTab,NULL,name)))
2909 werror(E_DUPLICATE_LABEL,label->name);
2911 addSym (LabelTab, label, name,label->level,0);
2914 label->key = labelKey++ ;
2915 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
2921 /*-----------------------------------------------------------------*/
2922 /* createCase - generates the parsetree for a case statement */
2923 /*-----------------------------------------------------------------*/
2924 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
2926 char caseLbl[SDCC_NAME_MAX+1];
2930 /* if the switch statement does not exist */
2931 /* then case is out of context */
2933 werror(E_CASE_CONTEXT);
2937 caseVal = decorateType(resolveSymbols(caseVal));
2938 /* if not a constant then error */
2939 if (!IS_LITERAL(caseVal->ftype)) {
2940 werror(E_CASE_CONSTANT);
2944 /* if not a integer than error */
2945 if (!IS_INTEGRAL(caseVal->ftype)) {
2946 werror(E_CASE_NON_INTEGER);
2950 /* find the end of the switch values chain */
2951 if (!(val = swStat->values.switchVals.swVals))
2952 swStat->values.switchVals.swVals = caseVal->opval.val ;
2954 /* also order the cases according to value */
2956 int cVal = (int) floatFromVal(caseVal->opval.val);
2957 while (val && (int) floatFromVal(val) < cVal) {
2962 /* if we reached the end then */
2964 pval->next = caseVal->opval.val;
2966 /* we found a value greater than */
2967 /* the current value we must add this */
2968 /* before the value */
2969 caseVal->opval.val->next = val;
2971 /* if this was the first in chain */
2972 if (swStat->values.switchVals.swVals == val)
2973 swStat->values.switchVals.swVals =
2976 pval->next = caseVal->opval.val;
2981 /* create the case label */
2982 sprintf(caseLbl,"_case_%d_%d",
2983 swStat->values.switchVals.swNum,
2984 (int) floatFromVal(caseVal->opval.val));
2986 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
2991 /*-----------------------------------------------------------------*/
2992 /* createDefault - creates the parse tree for the default statement*/
2993 /*-----------------------------------------------------------------*/
2994 ast *createDefault (ast *swStat, ast *stmnt)
2996 char defLbl[SDCC_NAME_MAX+1];
2998 /* if the switch statement does not exist */
2999 /* then case is out of context */
3001 werror(E_CASE_CONTEXT);
3005 /* turn on the default flag */
3006 swStat->values.switchVals.swDefault = 1 ;
3008 /* create the label */
3009 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3010 return createLabel(newSymbol(defLbl,0),stmnt);
3013 /*-----------------------------------------------------------------*/
3014 /* createIf - creates the parsetree for the if statement */
3015 /*-----------------------------------------------------------------*/
3016 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3018 static int Lblnum = 0 ;
3020 symbol *ifTrue , *ifFalse, *ifEnd ;
3022 /* if neither exists */
3023 if (! elseBody && !ifBody)
3026 /* create the labels */
3027 sprintf (buffer,"_iffalse_%d",Lblnum);
3028 ifFalse = newSymbol (buffer,NestLevel);
3029 /* if no else body then end == false */
3033 sprintf (buffer,"_ifend_%d",Lblnum);
3034 ifEnd = newSymbol (buffer,NestLevel);
3037 sprintf (buffer,"_iftrue_%d",Lblnum);
3038 ifTrue = newSymbol (buffer,NestLevel);
3042 /* attach the ifTrue label to the top of it body */
3043 ifBody = createLabel(ifTrue,ifBody);
3044 /* attach a goto end to the ifBody if else is present */
3046 ifBody = newNode(NULLOP,ifBody,
3048 newAst_VALUE(symbolVal(ifEnd)),
3050 /* put the elseLabel on the else body */
3051 elseBody = createLabel (ifFalse,elseBody);
3052 /* out the end at the end of the body */
3053 elseBody = newNode(NULLOP,
3055 createLabel(ifEnd,NULL));
3058 ifBody = newNode(NULLOP,ifBody,
3059 createLabel(ifFalse,NULL));
3061 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3062 if (IS_IFX(condAst))
3065 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3067 return newNode(NULLOP,ifTree,
3068 newNode(NULLOP,ifBody,elseBody));
3072 /*-----------------------------------------------------------------*/
3073 /* createDo - creates parse tree for do */
3076 /* _docontinue_n: */
3077 /* condition_expression +-> trueLabel -> _dobody_n */
3079 /* +-> falseLabel-> _dobreak_n */
3081 /*-----------------------------------------------------------------*/
3082 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3083 symbol *falseLabel, ast *condAst, ast *doBody )
3088 /* if the body does not exist then it is simple */
3090 condAst = backPatchLabels(condAst,continueLabel,NULL);
3091 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3092 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3093 doTree->trueLabel = continueLabel ;
3094 doTree->falseLabel= NULL ;
3098 /* otherwise we have a body */
3099 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3101 /* attach the body label to the top */
3102 doBody = createLabel(trueLabel,doBody);
3103 /* attach the continue label to end of body */
3104 doBody = newNode(NULLOP, doBody,
3105 createLabel(continueLabel,NULL));
3107 /* now put the break label at the end */
3108 if (IS_IFX(condAst))
3111 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3113 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3115 /* putting it together */
3116 return newNode(NULLOP,doBody,doTree);
3119 /*-----------------------------------------------------------------*/
3120 /* createFor - creates parse tree for 'for' statement */
3123 /* condExpr +-> trueLabel -> _forbody_n */
3125 /* +-> falseLabel-> _forbreak_n */
3128 /* _forcontinue_n: */
3130 /* goto _forcond_n ; */
3132 /*-----------------------------------------------------------------*/
3133 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3134 symbol *falseLabel,symbol *condLabel ,
3135 ast *initExpr, ast *condExpr, ast *loopExpr,
3140 /* if loopexpression not present then we can generate it */
3141 /* the same way as a while */
3143 return newNode(NULLOP,initExpr,
3144 createWhile (trueLabel, continueLabel,
3145 falseLabel,condExpr, forBody ));
3146 /* vanilla for statement */
3147 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3149 if (condExpr && !IS_IFX(condExpr))
3150 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3153 /* attach condition label to condition */
3154 condExpr = createLabel(condLabel,condExpr);
3156 /* attach body label to body */
3157 forBody = createLabel(trueLabel,forBody);
3159 /* attach continue to forLoop expression & attach */
3160 /* goto the forcond @ and of loopExpression */
3161 loopExpr = createLabel(continueLabel,
3165 newAst_VALUE(symbolVal(condLabel)),
3167 /* now start putting them together */
3168 forTree = newNode(NULLOP,initExpr,condExpr);
3169 forTree = newNode(NULLOP,forTree,forBody);
3170 forTree = newNode(NULLOP,forTree,loopExpr);
3171 /* finally add the break label */
3172 forTree = newNode(NULLOP,forTree,
3173 createLabel(falseLabel,NULL));
3177 /*-----------------------------------------------------------------*/
3178 /* createWhile - creates parse tree for while statement */
3179 /* the while statement will be created as follows */
3181 /* _while_continue_n: */
3182 /* condition_expression +-> trueLabel -> _while_boby_n */
3184 /* +-> falseLabel -> _while_break_n*/
3185 /* _while_body_n: */
3187 /* goto _while_continue_n */
3188 /* _while_break_n: */
3189 /*-----------------------------------------------------------------*/
3190 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3191 symbol *falseLabel,ast *condExpr, ast *whileBody )
3195 /* put the continue label */
3196 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3197 condExpr = createLabel(continueLabel,condExpr);
3198 condExpr->lineno = 0;
3200 /* put the body label in front of the body */
3201 whileBody = createLabel(trueLabel,whileBody);
3202 whileBody->lineno = 0;
3203 /* put a jump to continue at the end of the body */
3204 /* and put break label at the end of the body */
3205 whileBody = newNode(NULLOP,
3208 newAst_VALUE(symbolVal(continueLabel)),
3209 createLabel(falseLabel,NULL)));
3211 /* put it all together */
3212 if ( IS_IFX(condExpr) )
3213 whileTree = condExpr ;
3215 whileTree = newNode (IFX, condExpr,NULL );
3216 /* put the true & false labels in place */
3217 whileTree->trueLabel = trueLabel ;
3218 whileTree->falseLabel= falseLabel;
3221 return newNode(NULLOP,whileTree,whileBody );
3224 /*-----------------------------------------------------------------*/
3225 /* optimizeGetHbit - get highest order bit of the expression */
3226 /*-----------------------------------------------------------------*/
3227 ast *optimizeGetHbit (ast *tree)
3230 /* if this is not a bit and */
3231 if (!IS_BITAND(tree))
3234 /* will look for tree of the form
3235 ( expr >> ((sizeof expr) -1) ) & 1 */
3236 if (!IS_AST_LIT_VALUE(tree->right))
3239 if (AST_LIT_VALUE(tree->right) != 1)
3242 if (!IS_RIGHT_OP(tree->left))
3245 if (!IS_AST_LIT_VALUE(tree->left->right))
3248 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3249 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3252 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3256 /*-----------------------------------------------------------------*/
3257 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3258 /*-----------------------------------------------------------------*/
3259 ast *optimizeRRCRLC ( ast *root )
3261 /* will look for trees of the form
3262 (?expr << 1) | (?expr >> 7) or
3263 (?expr >> 7) | (?expr << 1) will make that
3264 into a RLC : operation ..
3266 (?expr >> 1) | (?expr << 7) or
3267 (?expr << 7) | (?expr >> 1) will make that
3268 into a RRC operation
3269 note : by 7 I mean (number of bits required to hold the
3271 /* if the root operations is not a | operation the not */
3272 if (!IS_BITOR(root))
3275 /* I have to think of a better way to match patterns this sucks */
3276 /* that aside let start looking for the first case : I use a the
3277 negative check a lot to improve the efficiency */
3278 /* (?expr << 1) | (?expr >> 7) */
3279 if (IS_LEFT_OP(root->left) &&
3280 IS_RIGHT_OP(root->right) ) {
3282 if (!SPEC_USIGN(TETYPE(root->left->left)))
3285 if (!IS_AST_LIT_VALUE(root->left->right) ||
3286 !IS_AST_LIT_VALUE(root->right->right))
3289 /* make sure it is the same expression */
3290 if (!isAstEqual(root->left->left,
3294 if (AST_LIT_VALUE(root->left->right) != 1 )
3297 if (AST_LIT_VALUE(root->right->right) !=
3298 (getSize(TTYPE(root->left->left))*8 - 1))
3301 /* whew got the first case : create the AST */
3302 return newNode(RLC,root->left->left,NULL);
3306 /* check for second case */
3307 /* (?expr >> 7) | (?expr << 1) */
3308 if (IS_LEFT_OP(root->right) &&
3309 IS_RIGHT_OP(root->left) ) {
3311 if (!SPEC_USIGN(TETYPE(root->left->left)))
3314 if (!IS_AST_LIT_VALUE(root->left->right) ||
3315 !IS_AST_LIT_VALUE(root->right->right))
3318 /* make sure it is the same symbol */
3319 if (!isAstEqual(root->left->left,
3323 if (AST_LIT_VALUE(root->right->right) != 1 )
3326 if (AST_LIT_VALUE(root->left->right) !=
3327 (getSize(TTYPE(root->left->left))*8 - 1))
3330 /* whew got the first case : create the AST */
3331 return newNode(RLC,root->left->left,NULL);
3336 /* third case for RRC */
3337 /* (?symbol >> 1) | (?symbol << 7) */
3338 if (IS_LEFT_OP(root->right) &&
3339 IS_RIGHT_OP(root->left) ) {
3341 if (!SPEC_USIGN(TETYPE(root->left->left)))
3344 if (!IS_AST_LIT_VALUE(root->left->right) ||
3345 !IS_AST_LIT_VALUE(root->right->right))
3348 /* make sure it is the same symbol */
3349 if (!isAstEqual(root->left->left,
3353 if (AST_LIT_VALUE(root->left->right) != 1 )
3356 if (AST_LIT_VALUE(root->right->right) !=
3357 (getSize(TTYPE(root->left->left))*8 - 1))
3360 /* whew got the first case : create the AST */
3361 return newNode(RRC,root->left->left,NULL);
3365 /* fourth and last case for now */
3366 /* (?symbol << 7) | (?symbol >> 1) */
3367 if (IS_RIGHT_OP(root->right) &&
3368 IS_LEFT_OP(root->left) ) {
3370 if (!SPEC_USIGN(TETYPE(root->left->left)))
3373 if (!IS_AST_LIT_VALUE(root->left->right) ||
3374 !IS_AST_LIT_VALUE(root->right->right))
3377 /* make sure it is the same symbol */
3378 if (!isAstEqual(root->left->left,
3382 if (AST_LIT_VALUE(root->right->right) != 1 )
3385 if (AST_LIT_VALUE(root->left->right) !=
3386 (getSize(TTYPE(root->left->left))*8 - 1))
3389 /* whew got the first case : create the AST */
3390 return newNode(RRC,root->left->left,NULL);
3394 /* not found return root */
3398 /*-----------------------------------------------------------------*/
3399 /* optimizeCompare - otimizes compares for bit variables */
3400 /*-----------------------------------------------------------------*/
3401 ast *optimizeCompare ( ast *root )
3403 ast *optExpr = NULL;
3406 unsigned int litValue ;
3408 /* if nothing then return nothing */
3412 /* if not a compare op then do leaves */
3413 if (!IS_COMPARE_OP(root)) {
3414 root->left = optimizeCompare (root->left);
3415 root->right= optimizeCompare (root->right);
3419 /* if left & right are the same then depending
3420 of the operation do */
3421 if (isAstEqual(root->left,root->right)) {
3422 switch (root->opval.op) {
3426 optExpr = newAst_VALUE(constVal("0"));
3431 optExpr = newAst_VALUE(constVal("1"));
3435 return decorateType(optExpr);
3438 vleft = (root->left->type == EX_VALUE ?
3439 root->left->opval.val : NULL );
3441 vright = (root->right->type == EX_VALUE ?
3442 root->right->opval.val : NULL);
3444 /* if left is a BITVAR in BITSPACE */
3445 /* and right is a LITERAL then opt-*/
3446 /* imize else do nothing */
3447 if (vleft && vright &&
3448 IS_BITVAR(vleft->etype) &&
3449 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3450 IS_LITERAL(vright->etype)) {
3452 /* if right side > 1 then comparison may never succeed */
3453 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3454 werror(W_BAD_COMPARE);
3459 switch (root->opval.op) {
3460 case '>' : /* bit value greater than 1 cannot be */
3461 werror(W_BAD_COMPARE);
3465 case '<' : /* bit value < 1 means 0 */
3467 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3470 case LE_OP : /* bit value <= 1 means no check */
3471 optExpr = newAst_VALUE(vright);
3474 case GE_OP : /* bit value >= 1 means only check for = */
3476 optExpr = newAst_VALUE(vleft);
3479 } else { /* literal is zero */
3480 switch (root->opval.op) {
3481 case '<' : /* bit value < 0 cannot be */
3482 werror(W_BAD_COMPARE);
3486 case '>' : /* bit value > 0 means 1 */
3488 optExpr = newAst_VALUE(vleft);
3491 case LE_OP : /* bit value <= 0 means no check */
3492 case GE_OP : /* bit value >= 0 means no check */
3493 werror(W_BAD_COMPARE);
3497 case EQ_OP : /* bit == 0 means ! of bit */
3498 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3502 return decorateType(resolveSymbols(optExpr));
3503 } /* end-of-if of BITVAR */
3508 /*-----------------------------------------------------------------*/
3509 /* addSymToBlock : adds the symbol to the first block we find */
3510 /*-----------------------------------------------------------------*/
3511 void addSymToBlock (symbol *sym, ast *tree)
3513 /* reached end of tree or a leaf */
3514 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3518 if (IS_AST_OP(tree) &&
3519 tree->opval.op == BLOCK ) {
3521 symbol *lsym = copySymbol(sym);
3523 lsym->next = AST_VALUES(tree,sym);
3524 AST_VALUES(tree,sym) = lsym ;
3528 addSymToBlock(sym,tree->left);
3529 addSymToBlock(sym,tree->right);
3532 /*-----------------------------------------------------------------*/
3533 /* processRegParms - do processing for register parameters */
3534 /*-----------------------------------------------------------------*/
3535 static void processRegParms (value *args, ast *body)
3538 if (IS_REGPARM(args->etype))
3539 addSymToBlock(args->sym,body);
3544 /*-----------------------------------------------------------------*/
3545 /* resetParmKey - resets the operandkeys for the symbols */
3546 /*-----------------------------------------------------------------*/
3547 DEFSETFUNC(resetParmKey)
3558 /*-----------------------------------------------------------------*/
3559 /* createFunction - This is the key node that calls the iCode for */
3560 /* generating the code for a function. Note code */
3561 /* is generated function by function, later when */
3562 /* add inter-procedural analysis this will change */
3563 /*-----------------------------------------------------------------*/
3564 ast *createFunction (symbol *name, ast *body )
3570 iCode *piCode = NULL;
3572 /* if check function return 0 then some problem */
3573 if (checkFunction (name) == 0)
3576 /* create a dummy block if none exists */
3578 body = newNode(BLOCK,NULL,NULL);
3582 /* check if the function name already in the symbol table */
3583 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3585 /* special case for compiler defined functions
3586 we need to add the name to the publics list : this
3587 actually means we are now compiling the compiler
3590 addSet(&publics,name);
3595 allocVariables(name);
3597 name->lastLine = yylineno;
3599 processFuncArgs(currFunc,0);
3601 /* set the stack pointer */
3602 /* PENDING: check this for the mcs51 */
3603 stackPtr = -port->stack.direction * port->stack.call_overhead;
3604 if (IS_ISR(name->etype))
3605 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3606 if (IS_RENT(name->etype) || options.stackAuto)
3607 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3609 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3611 fetype = getSpec(name->type); /* get the specifier for the function */
3612 /* if this is a reentrant function then */
3613 if (IS_RENT(fetype))
3616 allocParms (name->args); /* allocate the parameters */
3618 /* do processing for parameters that are passed in registers */
3619 processRegParms (name->args,body);
3621 /* set the stack pointer */
3625 /* allocate & autoinit the block variables */
3626 processBlockVars (body, &stack,ALLOCATE);
3628 /* save the stack information */
3629 if (options.useXstack)
3630 name->xstack = SPEC_STAK(fetype) = stack;
3632 name->stack = SPEC_STAK(fetype) = stack;
3634 /* name needs to be mangled */
3635 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3637 body = resolveSymbols(body); /* resolve the symbols */
3638 body = decorateType (body); /* propagateType & do semantic checks */
3640 ex = newAst_VALUE(symbolVal(name)); /* create name */
3641 ex = newNode (FUNCTION,ex,body);
3642 ex->values.args = name->args ;
3645 werror(E_FUNC_NO_CODE,name->name);
3649 /* create the node & generate intermediate code */
3650 codeOutFile = code->oFile;
3651 piCode = iCodeFromAst(ex);
3654 werror(E_FUNC_NO_CODE,name->name);
3658 eBBlockFromiCode(piCode);
3660 /* if there are any statics then do them */
3662 codeOutFile = statsg->oFile;
3663 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3669 /* dealloc the block variables */
3670 processBlockVars(body, &stack,DEALLOCATE);
3671 /* deallocate paramaters */
3672 deallocParms(name->args);
3674 if (IS_RENT(fetype))
3677 /* we are done freeup memory & cleanup */
3682 addSet(&operKeyReset,name);
3683 applyToSet(operKeyReset,resetParmKey);
3685 if (options.debug && !options.nodebug)
3686 cdbStructBlock(1,cdbFile);
3688 cleanUpLevel(LabelTab,0);
3689 cleanUpBlock(StructTab,1);
3690 cleanUpBlock(TypedefTab,1);
3692 xstack->syms = NULL;
3693 istack->syms = NULL;