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 *, sym_link *, initList *, ast *);
53 ast *createIvalCharPtr (ast *, sym_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 = (sym_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(sym_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, sym_link *type, sym_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 sym_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,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,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, 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, 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,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, 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)),
1490 replLoopSym(loop->left, sym);
1492 rloop = newNode(NULLOP,
1494 newAst_VALUE(symbolVal(sym)),
1495 newNode('-',end,init)),
1496 createLabel(AST_FOR(loop,continueLabel),
1501 newAst_VALUE(symbolVal(sym)),
1502 newAst_VALUE(constVal("1"))),
1505 return decorateType(rloop);
1509 #define DEMAND_INTEGER_PROMOTION
1511 #ifdef DEMAND_INTEGER_PROMOTION
1513 /*-----------------------------------------------------------------*/
1514 /* walk a tree looking for the leaves. Add a typecast to the given */
1515 /* type to each value leaf node. */
1516 /*-----------------------------------------------------------------*/
1517 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1521 /* WTF? We should never get here. */
1525 if (!node->left && !node->right)
1527 /* We're at a leaf; if it's a value, apply the typecast */
1528 if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1530 *parentPtr = newNode(CAST,
1531 newAst_LINK(copyLinkChain(type)),
1539 pushTypeCastToLeaves(type, node->left, &(node->left));
1543 pushTypeCastToLeaves(type, node->right, &(node->right));
1550 /*-----------------------------------------------------------------*/
1551 /* Given an assignment operation in a tree, determine if the LHS */
1552 /* (the result) has a different (integer) type than the RHS. */
1553 /* If so, walk the RHS and add a typecast to the type of the LHS */
1554 /* to all leaf nodes. */
1555 /*-----------------------------------------------------------------*/
1556 void propAsgType(ast *tree)
1558 #ifdef DEMAND_INTEGER_PROMOTION
1559 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1561 /* Nothing to do here... */
1565 if (getSize(LTYPE(tree)) != getSize(RTYPE(tree)))
1567 pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1574 /*-----------------------------------------------------------------*/
1575 /* decorateType - compute type for this tree also does type cheking*/
1576 /* this is done bottom up, since type have to flow upwards*/
1577 /* it also does constant folding, and paramater checking */
1578 /*-----------------------------------------------------------------*/
1579 ast *decorateType (ast *tree)
1587 /* if already has type then do nothing */
1588 if ( tree->decorated )
1591 tree->decorated = 1;
1593 /* print the line */
1594 /* if not block & function */
1595 if ( tree->type == EX_OP &&
1596 ( tree->opval.op != FUNCTION &&
1597 tree->opval.op != BLOCK &&
1598 tree->opval.op != NULLOP )) {
1599 filename = tree->filename ;
1600 lineno = tree->lineno ;
1603 /* if any child is an error | this one is an error do nothing */
1604 if ( tree->isError ||
1605 ( tree->left && tree->left->isError) ||
1606 ( tree->right && tree->right->isError ))
1609 /*------------------------------------------------------------------*/
1610 /*----------------------------*/
1611 /* leaf has been reached */
1612 /*----------------------------*/
1613 /* if this is of type value */
1614 /* just get the type */
1615 if ( tree->type == EX_VALUE ) {
1617 if ( IS_LITERAL(tree->opval.val->etype) ) {
1619 /* if this is a character array then declare it */
1620 if (IS_ARRAY(tree->opval.val->type))
1621 tree->opval.val = stringToSymbol(tree->opval.val);
1623 /* otherwise just copy the type information */
1624 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1625 if (funcInChain(tree->opval.val->type)) {
1626 tree->hasVargs = tree->opval.val->sym->hasVargs;
1627 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1632 if ( tree->opval.val->sym ) {
1633 /* if the undefined flag is set then give error message */
1634 if (tree->opval.val->sym->undefined ) {
1635 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1637 TTYPE(tree) = TETYPE(tree) =
1638 tree->opval.val->type = tree->opval.val->sym->type =
1639 tree->opval.val->etype = tree->opval.val->sym->etype =
1640 copyLinkChain(INTTYPE);
1644 /* if impilicit i.e. struct/union member then no type */
1645 if (tree->opval.val->sym->implicit )
1646 TTYPE(tree) = TETYPE(tree) = NULL ;
1650 /* else copy the type */
1651 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1653 /* and mark it as referenced */
1654 tree->opval.val->sym->isref = 1;
1655 /* if this is of type function or function pointer */
1656 if (funcInChain(tree->opval.val->type)) {
1657 tree->hasVargs = tree->opval.val->sym->hasVargs;
1658 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1668 /* if type link for the case of cast */
1669 if ( tree->type == EX_LINK ) {
1670 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1677 dtl = decorateType (tree->left);
1678 dtr = decorateType (tree->right);
1680 /* this is to take care of situations
1681 when the tree gets rewritten */
1682 if (dtl != tree->left)
1684 if (dtr != tree->right)
1688 /* depending on type of operator do */
1690 switch (tree->opval.op) {
1691 /*------------------------------------------------------------------*/
1692 /*----------------------------*/
1694 /*----------------------------*/
1697 /* determine which is the array & which the index */
1698 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1700 ast *tempTree = tree->left ;
1701 tree->left = tree->right ;
1702 tree->right= tempTree ;
1705 /* first check if this is a array or a pointer */
1706 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1707 werror(E_NEED_ARRAY_PTR,"[]");
1708 goto errorTreeReturn ;
1711 /* check if the type of the idx */
1712 if (!IS_INTEGRAL(RTYPE(tree))) {
1713 werror(E_IDX_NOT_INT);
1714 goto errorTreeReturn ;
1717 /* if the left is an rvalue then error */
1719 werror(E_LVALUE_REQUIRED,"array access");
1720 goto errorTreeReturn ;
1723 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1726 /*------------------------------------------------------------------*/
1727 /*----------------------------*/
1729 /*----------------------------*/
1731 /* if this is not a structure */
1732 if (!IS_STRUCT(LTYPE(tree))) {
1733 werror(E_STRUCT_UNION,".");
1734 goto errorTreeReturn ;
1736 TTYPE(tree) = structElemType (LTYPE(tree),
1737 (tree->right->type == EX_VALUE ?
1738 tree->right->opval.val : NULL ),&tree->args);
1739 TETYPE(tree) = getSpec(TTYPE(tree));
1742 /*------------------------------------------------------------------*/
1743 /*----------------------------*/
1744 /* struct/union pointer */
1745 /*----------------------------*/
1747 /* if not pointer to a structure */
1748 if (!IS_PTR(LTYPE(tree))) {
1750 goto errorTreeReturn ;
1753 if (!IS_STRUCT(LTYPE(tree)->next)) {
1754 werror(E_STRUCT_UNION,"->");
1755 goto errorTreeReturn ;
1758 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1759 (tree->right->type == EX_VALUE ?
1760 tree->right->opval.val : NULL ),&tree->args);
1761 TETYPE(tree) = getSpec(TTYPE(tree));
1764 /*------------------------------------------------------------------*/
1765 /*----------------------------*/
1766 /* ++/-- operation */
1767 /*----------------------------*/
1768 case INC_OP: /* incerement operator unary so left only */
1771 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1772 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1773 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1774 werror(E_CODE_WRITE,"++/--");
1783 /*------------------------------------------------------------------*/
1784 /*----------------------------*/
1786 /*----------------------------*/
1787 case '&': /* can be unary */
1788 /* if right is NULL then unary operation */
1789 if ( tree->right ) /* not an unary operation */ {
1791 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1792 werror(E_BITWISE_OP);
1793 werror(E_CONTINUE,"left & right types are ");
1794 printTypeChain(LTYPE(tree),stderr);
1795 fprintf(stderr,",");
1796 printTypeChain(RTYPE(tree),stderr);
1797 fprintf(stderr,"\n");
1798 goto errorTreeReturn ;
1801 /* if they are both literal */
1802 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1803 tree->type = EX_VALUE ;
1804 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1805 valFromType(RETYPE(tree)),'&');
1807 tree->right = tree->left = NULL;
1808 TETYPE(tree) = tree->opval.val->etype ;
1809 TTYPE(tree) = tree->opval.val->type;
1813 /* see if this is a GETHBIT operation if yes
1816 ast *otree = optimizeGetHbit(tree);
1819 return decorateType(otree);
1822 /* if right or left is literal then result of that type*/
1823 if (IS_LITERAL(RTYPE(tree))) {
1825 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1826 TETYPE(tree) = getSpec(TTYPE(tree));
1827 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1830 if (IS_LITERAL(LTYPE(tree))) {
1831 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1832 TETYPE(tree) = getSpec(TTYPE(tree));
1833 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1838 computeType (LTYPE(tree), RTYPE(tree));
1839 TETYPE(tree) = getSpec(TTYPE(tree));
1842 LRVAL(tree) = RRVAL(tree) = 1;
1846 /*------------------------------------------------------------------*/
1847 /*----------------------------*/
1849 /*----------------------------*/
1851 p->class = DECLARATOR;
1852 /* if bit field then error */
1853 if (IS_BITVAR(tree->left->etype)) {
1854 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1855 goto errorTreeReturn ;
1858 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1859 werror (E_ILLEGAL_ADDR,"address of register variable");
1860 goto errorTreeReturn;
1863 if (IS_FUNC(LTYPE(tree))) {
1864 werror(E_ILLEGAL_ADDR,"address of function");
1865 goto errorTreeReturn ;
1869 werror(E_LVALUE_REQUIRED,"address of");
1870 goto errorTreeReturn ;
1872 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1873 DCL_TYPE(p) = CPOINTER ;
1874 DCL_PTR_CONST(p) = port->mem.code_ro;
1877 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1878 DCL_TYPE(p) = FPOINTER;
1880 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1881 DCL_TYPE(p) = PPOINTER ;
1883 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1884 DCL_TYPE(p) = IPOINTER ;
1886 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1887 DCL_TYPE(p) = EEPPOINTER ;
1889 DCL_TYPE(p) = POINTER ;
1891 if (IS_AST_SYM_VALUE(tree->left)) {
1892 AST_SYMBOL(tree->left)->addrtaken = 1;
1893 AST_SYMBOL(tree->left)->allocreq = 1;
1896 p->next = LTYPE(tree);
1898 TETYPE(tree) = getSpec(TTYPE(tree));
1899 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1900 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1905 /*------------------------------------------------------------------*/
1906 /*----------------------------*/
1908 /*----------------------------*/
1910 /* if the rewrite succeeds then don't go any furthur */
1912 ast *wtree = optimizeRRCRLC ( tree );
1914 return decorateType(wtree) ;
1916 /*------------------------------------------------------------------*/
1917 /*----------------------------*/
1919 /*----------------------------*/
1921 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1922 werror(E_BITWISE_OP);
1923 werror(E_CONTINUE,"left & right types are ");
1924 printTypeChain(LTYPE(tree),stderr);
1925 fprintf(stderr,",");
1926 printTypeChain(RTYPE(tree),stderr);
1927 fprintf(stderr,"\n");
1928 goto errorTreeReturn ;
1931 /* if they are both literal then */
1932 /* rewrite the tree */
1933 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1934 tree->type = EX_VALUE ;
1935 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1936 valFromType(RETYPE(tree)),
1938 tree->right = tree->left = NULL;
1939 TETYPE(tree) = tree->opval.val->etype;
1940 TTYPE(tree) = tree->opval.val->type;
1943 LRVAL(tree) = RRVAL(tree) = 1;
1944 TETYPE(tree) = getSpec (TTYPE(tree) =
1945 computeType(LTYPE(tree),
1948 /*------------------------------------------------------------------*/
1949 /*----------------------------*/
1951 /*----------------------------*/
1953 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1954 werror(E_INVALID_OP,"divide");
1955 goto errorTreeReturn ;
1957 /* if they are both literal then */
1958 /* rewrite the tree */
1959 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1960 tree->type = EX_VALUE ;
1961 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1962 valFromType(RETYPE(tree)));
1963 tree->right = tree->left = NULL;
1964 TETYPE(tree) = getSpec(TTYPE(tree) =
1965 tree->opval.val->type);
1968 LRVAL(tree) = RRVAL(tree) = 1;
1969 TETYPE(tree) = getSpec (TTYPE(tree) =
1970 computeType(LTYPE(tree),
1974 /*------------------------------------------------------------------*/
1975 /*----------------------------*/
1977 /*----------------------------*/
1979 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1980 werror(E_BITWISE_OP);
1981 werror(E_CONTINUE,"left & right types are ");
1982 printTypeChain(LTYPE(tree),stderr);
1983 fprintf(stderr,",");
1984 printTypeChain(RTYPE(tree),stderr);
1985 fprintf(stderr,"\n");
1986 goto errorTreeReturn ;
1988 /* if they are both literal then */
1989 /* rewrite the tree */
1990 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1991 tree->type = EX_VALUE ;
1992 tree->opval.val = valMod (valFromType(LETYPE(tree)),
1993 valFromType(RETYPE(tree)));
1994 tree->right = tree->left = NULL;
1995 TETYPE(tree) = getSpec(TTYPE(tree) =
1996 tree->opval.val->type);
1999 LRVAL(tree) = RRVAL(tree) = 1;
2000 TETYPE(tree) = getSpec (TTYPE(tree) =
2001 computeType(LTYPE(tree),
2005 /*------------------------------------------------------------------*/
2006 /*----------------------------*/
2007 /* address dereference */
2008 /*----------------------------*/
2009 case '*': /* can be unary : if right is null then unary operation */
2010 if ( ! tree->right ) {
2011 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2013 goto errorTreeReturn ;
2017 werror(E_LVALUE_REQUIRED,"pointer deref");
2018 goto errorTreeReturn ;
2020 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2021 LTYPE(tree)->next : NULL );
2022 TETYPE(tree) = getSpec(TTYPE(tree));
2023 tree->args = tree->left->args ;
2024 tree->hasVargs = tree->left->hasVargs ;
2025 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2029 /*------------------------------------------------------------------*/
2030 /*----------------------------*/
2031 /* multiplication */
2032 /*----------------------------*/
2033 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2034 werror(E_INVALID_OP,"multiplication");
2035 goto errorTreeReturn ;
2038 /* if they are both literal then */
2039 /* rewrite the tree */
2040 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2041 tree->type = EX_VALUE ;
2042 tree->opval.val = valMult (valFromType(LETYPE(tree)),
2043 valFromType(RETYPE(tree)));
2044 tree->right = tree->left = NULL;
2045 TETYPE(tree) = getSpec(TTYPE(tree) =
2046 tree->opval.val->type);
2050 /* if left is a literal exchange left & right */
2051 if (IS_LITERAL(LTYPE(tree))) {
2052 ast *tTree = tree->left ;
2053 tree->left = tree->right ;
2054 tree->right= tTree ;
2057 LRVAL(tree) = RRVAL(tree) = 1;
2058 TETYPE(tree) = getSpec (TTYPE(tree) =
2059 computeType(LTYPE(tree),
2063 /*------------------------------------------------------------------*/
2064 /*----------------------------*/
2065 /* unary '+' operator */
2066 /*----------------------------*/
2069 if ( ! tree->right ) {
2070 if (!IS_INTEGRAL(LTYPE(tree))) {
2071 werror(E_UNARY_OP,'+');
2072 goto errorTreeReturn ;
2075 /* if left is a literal then do it */
2076 if (IS_LITERAL(LTYPE(tree))) {
2077 tree->type = EX_VALUE ;
2078 tree->opval.val = valFromType(LETYPE(tree));
2080 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2084 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2088 /*------------------------------------------------------------------*/
2089 /*----------------------------*/
2091 /*----------------------------*/
2093 /* this is not a unary operation */
2094 /* if both pointers then problem */
2095 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2096 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2097 werror(E_PTR_PLUS_PTR);
2098 goto errorTreeReturn ;
2101 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2102 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2103 werror(E_PLUS_INVALID,"+");
2104 goto errorTreeReturn ;
2107 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2108 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2109 werror(E_PLUS_INVALID,"+");
2110 goto errorTreeReturn;
2112 /* if they are both literal then */
2113 /* rewrite the tree */
2114 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2115 tree->type = EX_VALUE ;
2116 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2117 valFromType(RETYPE(tree)));
2118 tree->right = tree->left = NULL;
2119 TETYPE(tree) = getSpec(TTYPE(tree) =
2120 tree->opval.val->type);
2124 /* if the right is a pointer or left is a literal
2125 xchange left & right */
2126 if (IS_ARRAY(RTYPE(tree)) ||
2127 IS_PTR(RTYPE(tree)) ||
2128 IS_LITERAL(LTYPE(tree))) {
2129 ast *tTree = tree->left ;
2130 tree->left = tree->right ;
2131 tree->right= tTree ;
2134 LRVAL(tree) = RRVAL(tree) = 1;
2135 /* if the left is a pointer */
2136 if (IS_PTR(LTYPE(tree)))
2137 TETYPE(tree) = getSpec(TTYPE(tree) =
2140 TETYPE(tree) = getSpec(TTYPE(tree) =
2141 computeType(LTYPE(tree),
2145 /*------------------------------------------------------------------*/
2146 /*----------------------------*/
2148 /*----------------------------*/
2149 case '-' : /* can be unary */
2150 /* if right is null then unary */
2151 if ( ! tree->right ) {
2153 if (!IS_ARITHMETIC(LTYPE(tree))) {
2154 werror(E_UNARY_OP,tree->opval.op);
2155 goto errorTreeReturn ;
2158 /* if left is a literal then do it */
2159 if (IS_LITERAL(LTYPE(tree))) {
2160 tree->type = EX_VALUE ;
2161 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2163 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2167 TTYPE(tree) = LTYPE(tree);
2171 /*------------------------------------------------------------------*/
2172 /*----------------------------*/
2174 /*----------------------------*/
2176 if (!(IS_PTR(LTYPE(tree)) ||
2177 IS_ARRAY(LTYPE(tree)) ||
2178 IS_ARITHMETIC(LTYPE(tree)))) {
2179 werror(E_PLUS_INVALID,"-");
2180 goto errorTreeReturn ;
2183 if (!(IS_PTR(RTYPE(tree)) ||
2184 IS_ARRAY(RTYPE(tree)) ||
2185 IS_ARITHMETIC(RTYPE(tree)))) {
2186 werror(E_PLUS_INVALID,"-");
2187 goto errorTreeReturn ;
2190 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2191 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2192 IS_INTEGRAL(RTYPE(tree))) ) {
2193 werror(E_PLUS_INVALID,"-");
2194 goto errorTreeReturn ;
2197 /* if they are both literal then */
2198 /* rewrite the tree */
2199 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2200 tree->type = EX_VALUE ;
2201 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2202 valFromType(RETYPE(tree)));
2203 tree->right = tree->left = NULL;
2204 TETYPE(tree) = getSpec(TTYPE(tree) =
2205 tree->opval.val->type);
2209 /* if the left & right are equal then zero */
2210 if (isAstEqual(tree->left,tree->right)) {
2211 tree->type = EX_VALUE;
2212 tree->left = tree->right = NULL;
2213 tree->opval.val = constVal("0");
2214 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2218 /* if both of them are pointers or arrays then */
2219 /* the result is going to be an integer */
2220 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2221 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2222 TETYPE(tree) = TTYPE(tree) = newIntLink();
2224 /* if only the left is a pointer */
2225 /* then result is a pointer */
2226 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2227 TETYPE(tree) = getSpec(TTYPE(tree) =
2230 TETYPE(tree) = getSpec (TTYPE(tree) =
2231 computeType(LTYPE(tree),
2233 LRVAL(tree) = RRVAL(tree) = 1;
2236 /*------------------------------------------------------------------*/
2237 /*----------------------------*/
2239 /*----------------------------*/
2241 /* can be only integral type */
2242 if (!IS_INTEGRAL(LTYPE(tree))) {
2243 werror(E_UNARY_OP,tree->opval.op);
2244 goto errorTreeReturn ;
2247 /* if left is a literal then do it */
2248 if (IS_LITERAL(LTYPE(tree))) {
2249 tree->type = EX_VALUE ;
2250 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2252 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2256 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2259 /*------------------------------------------------------------------*/
2260 /*----------------------------*/
2262 /*----------------------------*/
2264 /* can be pointer */
2265 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2266 !IS_PTR(LTYPE(tree)) &&
2267 !IS_ARRAY(LTYPE(tree))) {
2268 werror(E_UNARY_OP,tree->opval.op);
2269 goto errorTreeReturn ;
2272 /* if left is a literal then do it */
2273 if (IS_LITERAL(LTYPE(tree))) {
2274 tree->type = EX_VALUE ;
2275 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2277 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2281 TTYPE(tree) = TETYPE(tree) = newCharLink();
2284 /*------------------------------------------------------------------*/
2285 /*----------------------------*/
2287 /*----------------------------*/
2290 TTYPE(tree) = LTYPE(tree);
2291 TETYPE(tree) = LETYPE(tree);
2295 TTYPE(tree) = TETYPE(tree) = newCharLink();
2300 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2301 werror(E_SHIFT_OP_INVALID);
2302 werror(E_CONTINUE,"left & right types are ");
2303 printTypeChain(LTYPE(tree),stderr);
2304 fprintf(stderr,",");
2305 printTypeChain(RTYPE(tree),stderr);
2306 fprintf(stderr,"\n");
2307 goto errorTreeReturn ;
2310 /* if they are both literal then */
2311 /* rewrite the tree */
2312 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2313 tree->type = EX_VALUE ;
2314 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2315 valFromType(RETYPE(tree)),
2316 (tree->opval.op == LEFT_OP ? 1 : 0));
2317 tree->right = tree->left = NULL;
2318 TETYPE(tree) = getSpec(TTYPE(tree) =
2319 tree->opval.val->type);
2322 /* if only the right side is a literal & we are
2323 shifting more than size of the left operand then zero */
2324 if (IS_LITERAL(RTYPE(tree)) &&
2325 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2326 (getSize(LTYPE(tree))*8)) {
2327 werror(W_SHIFT_CHANGED,
2328 (tree->opval.op == LEFT_OP ? "left" : "right"));
2329 tree->type = EX_VALUE;
2330 tree->left = tree->right = NULL;
2331 tree->opval.val = constVal("0");
2332 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2335 LRVAL(tree) = RRVAL(tree) = 1;
2336 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2337 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2339 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2343 /*------------------------------------------------------------------*/
2344 /*----------------------------*/
2346 /*----------------------------*/
2347 case CAST: /* change the type */
2348 /* cannot cast to an aggregate type */
2349 if (IS_AGGREGATE(LTYPE(tree))) {
2350 werror(E_CAST_ILLEGAL);
2351 goto errorTreeReturn ;
2354 /* if the right is a literal replace the tree */
2355 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2356 tree->type = EX_VALUE ;
2358 valCastLiteral(LTYPE(tree),
2359 floatFromVal(valFromType(RETYPE(tree))));
2362 TTYPE(tree) = tree->opval.val->type;
2365 TTYPE(tree) = LTYPE(tree);
2369 TETYPE(tree) = getSpec(TTYPE(tree));
2373 /*------------------------------------------------------------------*/
2374 /*----------------------------*/
2375 /* logical &&, || */
2376 /*----------------------------*/
2379 /* each must me arithmetic type or be a pointer */
2380 if (!IS_PTR(LTYPE(tree)) &&
2381 !IS_ARRAY(LTYPE(tree)) &&
2382 !IS_INTEGRAL(LTYPE(tree))) {
2383 werror(E_COMPARE_OP);
2384 goto errorTreeReturn ;
2387 if (!IS_PTR(RTYPE(tree)) &&
2388 !IS_ARRAY(RTYPE(tree)) &&
2389 !IS_INTEGRAL(RTYPE(tree))) {
2390 werror(E_COMPARE_OP);
2391 goto errorTreeReturn ;
2393 /* if they are both literal then */
2394 /* rewrite the tree */
2395 if (IS_LITERAL(RTYPE(tree)) &&
2396 IS_LITERAL(LTYPE(tree))) {
2397 tree->type = EX_VALUE ;
2398 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2399 valFromType(RETYPE(tree)),
2401 tree->right = tree->left = NULL;
2402 TETYPE(tree) = getSpec(TTYPE(tree) =
2403 tree->opval.val->type);
2406 LRVAL(tree) = RRVAL(tree) = 1;
2407 TTYPE(tree) = TETYPE(tree) = newCharLink();
2410 /*------------------------------------------------------------------*/
2411 /*----------------------------*/
2412 /* comparison operators */
2413 /*----------------------------*/
2421 ast *lt = optimizeCompare(tree);
2427 /* if they are pointers they must be castable */
2428 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2429 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2430 werror(E_COMPARE_OP);
2431 fprintf(stderr,"comparing type ");
2432 printTypeChain(LTYPE(tree),stderr);
2433 fprintf(stderr,"to type ");
2434 printTypeChain(RTYPE(tree),stderr);
2435 fprintf(stderr,"\n");
2436 goto errorTreeReturn ;
2439 /* else they should be promotable to one another */
2441 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2442 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2444 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2445 werror(E_COMPARE_OP);
2446 fprintf(stderr,"comparing type ");
2447 printTypeChain(LTYPE(tree),stderr);
2448 fprintf(stderr,"to type ");
2449 printTypeChain(RTYPE(tree),stderr);
2450 fprintf(stderr,"\n");
2451 goto errorTreeReturn ;
2455 /* if they are both literal then */
2456 /* rewrite the tree */
2457 if (IS_LITERAL(RTYPE(tree)) &&
2458 IS_LITERAL(LTYPE(tree))) {
2459 tree->type = EX_VALUE ;
2460 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2461 valFromType(RETYPE(tree)),
2463 tree->right = tree->left = NULL;
2464 TETYPE(tree) = getSpec(TTYPE(tree) =
2465 tree->opval.val->type);
2468 LRVAL(tree) = RRVAL(tree) = 1;
2469 TTYPE(tree) = TETYPE(tree) = newCharLink();
2472 /*------------------------------------------------------------------*/
2473 /*----------------------------*/
2475 /*----------------------------*/
2476 case SIZEOF : /* evaluate wihout code generation */
2477 /* change the type to a integer */
2478 tree->type = EX_VALUE;
2479 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2480 tree->opval.val = constVal(buffer);
2481 tree->right = tree->left = NULL;
2482 TETYPE(tree) = getSpec(TTYPE(tree) =
2483 tree->opval.val->type);
2486 /*------------------------------------------------------------------*/
2487 /*----------------------------*/
2488 /* conditional operator '?' */
2489 /*----------------------------*/
2491 /* the type is one on the left */
2492 TTYPE(tree) = LTYPE(tree);
2493 TETYPE(tree)= getSpec (TTYPE(tree));
2497 /* if they don't match we have a problem */
2498 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2499 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2500 goto errorTreeReturn ;
2503 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2504 TETYPE(tree)= getSpec(TTYPE(tree));
2508 /*------------------------------------------------------------------*/
2509 /*----------------------------*/
2510 /* assignment operators */
2511 /*----------------------------*/
2514 /* for these it must be both must be integral */
2515 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2516 !IS_ARITHMETIC(RTYPE(tree))) {
2517 werror (E_OPS_INTEGRAL);
2518 goto errorTreeReturn ;
2521 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2523 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2524 werror(E_CODE_WRITE," ");
2527 werror(E_LVALUE_REQUIRED,"*= or /=");
2528 goto errorTreeReturn ;
2541 /* for these it must be both must be integral */
2542 if (!IS_INTEGRAL(LTYPE(tree)) ||
2543 !IS_INTEGRAL(RTYPE(tree))) {
2544 werror (E_OPS_INTEGRAL);
2545 goto errorTreeReturn ;
2548 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2550 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2551 werror(E_CODE_WRITE," ");
2554 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2555 goto errorTreeReturn ;
2563 /*------------------------------------------------------------------*/
2564 /*----------------------------*/
2566 /*----------------------------*/
2568 if (!(IS_PTR(LTYPE(tree)) ||
2569 IS_ARITHMETIC(LTYPE(tree)))) {
2570 werror(E_PLUS_INVALID,"-=");
2571 goto errorTreeReturn ;
2574 if (!(IS_PTR(RTYPE(tree)) ||
2575 IS_ARITHMETIC(RTYPE(tree)))) {
2576 werror(E_PLUS_INVALID,"-=");
2577 goto errorTreeReturn ;
2580 TETYPE(tree) = getSpec (TTYPE(tree) =
2581 computeType(LTYPE(tree),
2584 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2585 werror(E_CODE_WRITE," ");
2588 werror(E_LVALUE_REQUIRED,"-=");
2589 goto errorTreeReturn ;
2597 /*------------------------------------------------------------------*/
2598 /*----------------------------*/
2600 /*----------------------------*/
2602 /* this is not a unary operation */
2603 /* if both pointers then problem */
2604 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2605 werror(E_PTR_PLUS_PTR);
2606 goto errorTreeReturn ;
2609 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2610 werror(E_PLUS_INVALID,"+=");
2611 goto errorTreeReturn ;
2614 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2615 werror(E_PLUS_INVALID,"+=");
2616 goto errorTreeReturn;
2619 TETYPE(tree) = getSpec (TTYPE(tree) =
2620 computeType(LTYPE(tree),
2623 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2624 werror(E_CODE_WRITE," ");
2627 werror(E_LVALUE_REQUIRED,"+=");
2628 goto errorTreeReturn ;
2631 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2632 tree->opval.op = '=';
2638 /*------------------------------------------------------------------*/
2639 /*----------------------------*/
2640 /* straight assignemnt */
2641 /*----------------------------*/
2643 /* cannot be an aggregate */
2644 if (IS_AGGREGATE(LTYPE(tree))) {
2645 werror(E_AGGR_ASSIGN);
2646 goto errorTreeReturn;
2649 /* they should either match or be castable */
2650 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2651 werror(E_TYPE_MISMATCH,"assignment"," ");
2652 fprintf(stderr,"type --> '");
2653 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2654 fprintf(stderr,"assigned to type --> '");
2655 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2656 goto errorTreeReturn ;
2659 /* if the left side of the tree is of type void
2660 then report error */
2661 if (IS_VOID(LTYPE(tree))) {
2662 werror(E_CAST_ZERO);
2663 fprintf(stderr,"type --> '");
2664 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2665 fprintf(stderr,"assigned to type --> '");
2666 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2669 /* extra checks for pointer types */
2670 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2671 !IS_GENPTR(LTYPE(tree))) {
2672 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2673 werror(W_PTR_ASSIGN);
2676 TETYPE(tree) = getSpec(TTYPE(tree) =
2680 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2681 werror(E_CODE_WRITE," ");
2684 werror(E_LVALUE_REQUIRED,"=");
2685 goto errorTreeReturn ;
2692 /*------------------------------------------------------------------*/
2693 /*----------------------------*/
2694 /* comma operator */
2695 /*----------------------------*/
2697 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2700 /*------------------------------------------------------------------*/
2701 /*----------------------------*/
2703 /*----------------------------*/
2708 if (processParms (tree->left,
2710 tree->right,&parmNumber))
2711 goto errorTreeReturn ;
2713 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2714 tree->left->args = reverseVal(tree->left->args);
2715 reverseParms(tree->right);
2718 tree->args = tree->left->args ;
2719 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2722 /*------------------------------------------------------------------*/
2723 /*----------------------------*/
2724 /* return statement */
2725 /*----------------------------*/
2730 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2731 werror(E_RETURN_MISMATCH);
2732 goto errorTreeReturn ;
2735 if (IS_VOID(currFunc->type->next)
2737 !IS_VOID(RTYPE(tree))) {
2738 werror(E_FUNC_VOID);
2739 goto errorTreeReturn ;
2742 /* if there is going to be a casing required then add it */
2743 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2745 #ifdef DEMAND_INTEGER_PROMOTION
2746 if (IS_INTEGRAL(currFunc->type->next))
2748 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2754 decorateType(newNode(CAST,
2755 newAst_LINK(copyLinkChain(currFunc->type->next)),
2759 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2766 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2767 werror(E_VOID_FUNC,currFunc->name);
2768 goto errorTreeReturn ;
2771 TTYPE(tree) = TETYPE(tree) = NULL ;
2774 /*------------------------------------------------------------------*/
2775 /*----------------------------*/
2776 /* switch statement */
2777 /*----------------------------*/
2779 /* the switch value must be an integer */
2780 if (!IS_INTEGRAL(LTYPE(tree))) {
2781 werror (E_SWITCH_NON_INTEGER);
2782 goto errorTreeReturn ;
2785 TTYPE(tree) = TETYPE(tree) = NULL ;
2788 /*------------------------------------------------------------------*/
2789 /*----------------------------*/
2791 /*----------------------------*/
2793 tree->left = backPatchLabels(tree->left,
2796 TTYPE(tree) = TETYPE(tree) = NULL;
2799 /*------------------------------------------------------------------*/
2800 /*----------------------------*/
2802 /*----------------------------*/
2805 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2806 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2807 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2809 /* if the for loop is reversible then
2810 reverse it otherwise do what we normally
2816 if (isLoopReversible (tree,&sym,&init,&end))
2817 return reverseLoop (tree,sym,init,end);
2819 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2820 AST_FOR(tree,continueLabel) ,
2821 AST_FOR(tree,falseLabel) ,
2822 AST_FOR(tree,condLabel) ,
2823 AST_FOR(tree,initExpr) ,
2824 AST_FOR(tree,condExpr) ,
2825 AST_FOR(tree,loopExpr),
2829 TTYPE(tree) = TETYPE(tree) = NULL ;
2833 /* some error found this tree will be killed */
2835 TTYPE(tree) = TETYPE(tree) = newCharLink();
2836 tree->opval.op = NULLOP ;
2842 /*-----------------------------------------------------------------*/
2843 /* sizeofOp - processes size of operation */
2844 /*-----------------------------------------------------------------*/
2845 value *sizeofOp( sym_link *type)
2849 /* get the size and convert it to character */
2850 sprintf (buff,"%d", getSize(type));
2852 /* now convert into value */
2853 return constVal (buff);
2857 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2858 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2859 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2860 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2861 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2862 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2863 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2865 /*-----------------------------------------------------------------*/
2866 /* backPatchLabels - change and or not operators to flow control */
2867 /*-----------------------------------------------------------------*/
2868 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2874 if ( ! (IS_ANDORNOT(tree)))
2877 /* if this an and */
2879 static int localLbl = 0 ;
2880 symbol *localLabel ;
2882 sprintf (buffer,"_and_%d",localLbl++);
2883 localLabel = newSymbol(buffer,NestLevel);
2885 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2887 /* if left is already a IFX then just change the if true label in that */
2888 if (!IS_IFX(tree->left))
2889 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2891 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2892 /* right is a IFX then just join */
2893 if (IS_IFX(tree->right))
2894 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2896 tree->right = createLabel(localLabel,tree->right);
2897 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2899 return newNode(NULLOP,tree->left,tree->right);
2902 /* if this is an or operation */
2904 static int localLbl = 0 ;
2905 symbol *localLabel ;
2907 sprintf (buffer,"_or_%d",localLbl++);
2908 localLabel = newSymbol(buffer,NestLevel);
2910 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2912 /* if left is already a IFX then just change the if true label in that */
2913 if (!IS_IFX(tree->left))
2914 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2916 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2917 /* right is a IFX then just join */
2918 if (IS_IFX(tree->right))
2919 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2921 tree->right = createLabel(localLabel,tree->right);
2922 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2924 return newNode(NULLOP,tree->left,tree->right);
2929 int wasnot = IS_NOT(tree->left);
2930 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2932 /* if the left is already a IFX */
2933 if ( ! IS_IFX(tree->left) )
2934 tree->left = newNode (IFX,tree->left,NULL);
2937 tree->left->trueLabel = trueLabel ;
2938 tree->left->falseLabel= falseLabel ;
2940 tree->left->trueLabel = falseLabel ;
2941 tree->left->falseLabel= trueLabel ;
2947 tree->trueLabel = trueLabel ;
2948 tree->falseLabel= falseLabel;
2955 /*-----------------------------------------------------------------*/
2956 /* createBlock - create expression tree for block */
2957 /*-----------------------------------------------------------------*/
2958 ast *createBlock ( symbol *decl, ast *body )
2962 /* if the block has nothing */
2966 ex = newNode(BLOCK,NULL,body);
2967 ex->values.sym = decl ;
2969 ex->right = ex->right ;
2975 /*-----------------------------------------------------------------*/
2976 /* createLabel - creates the expression tree for labels */
2977 /*-----------------------------------------------------------------*/
2978 ast *createLabel ( symbol *label, ast *stmnt )
2981 char name[SDCC_NAME_MAX+1];
2984 /* must create fresh symbol if the symbol name */
2985 /* exists in the symbol table, since there can */
2986 /* be a variable with the same name as the labl */
2987 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2988 (csym->level == label->level))
2989 label = newSymbol(label->name,label->level);
2991 /* change the name before putting it in add _*/
2992 sprintf (name,"%s",label->name);
2994 /* put the label in the LabelSymbol table */
2995 /* but first check if a label of the same */
2997 if ( (csym = findSym(LabelTab,NULL,name)))
2998 werror(E_DUPLICATE_LABEL,label->name);
3000 addSym (LabelTab, label, name,label->level,0);
3003 label->key = labelKey++ ;
3004 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3010 /*-----------------------------------------------------------------*/
3011 /* createCase - generates the parsetree for a case statement */
3012 /*-----------------------------------------------------------------*/
3013 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
3015 char caseLbl[SDCC_NAME_MAX+1];
3019 /* if the switch statement does not exist */
3020 /* then case is out of context */
3022 werror(E_CASE_CONTEXT);
3026 caseVal = decorateType(resolveSymbols(caseVal));
3027 /* if not a constant then error */
3028 if (!IS_LITERAL(caseVal->ftype)) {
3029 werror(E_CASE_CONSTANT);
3033 /* if not a integer than error */
3034 if (!IS_INTEGRAL(caseVal->ftype)) {
3035 werror(E_CASE_NON_INTEGER);
3039 /* find the end of the switch values chain */
3040 if (!(val = swStat->values.switchVals.swVals))
3041 swStat->values.switchVals.swVals = caseVal->opval.val ;
3043 /* also order the cases according to value */
3045 int cVal = (int) floatFromVal(caseVal->opval.val);
3046 while (val && (int) floatFromVal(val) < cVal) {
3051 /* if we reached the end then */
3053 pval->next = caseVal->opval.val;
3055 /* we found a value greater than */
3056 /* the current value we must add this */
3057 /* before the value */
3058 caseVal->opval.val->next = val;
3060 /* if this was the first in chain */
3061 if (swStat->values.switchVals.swVals == val)
3062 swStat->values.switchVals.swVals =
3065 pval->next = caseVal->opval.val;
3070 /* create the case label */
3071 sprintf(caseLbl,"_case_%d_%d",
3072 swStat->values.switchVals.swNum,
3073 (int) floatFromVal(caseVal->opval.val));
3075 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3080 /*-----------------------------------------------------------------*/
3081 /* createDefault - creates the parse tree for the default statement*/
3082 /*-----------------------------------------------------------------*/
3083 ast *createDefault (ast *swStat, ast *stmnt)
3085 char defLbl[SDCC_NAME_MAX+1];
3087 /* if the switch statement does not exist */
3088 /* then case is out of context */
3090 werror(E_CASE_CONTEXT);
3094 /* turn on the default flag */
3095 swStat->values.switchVals.swDefault = 1 ;
3097 /* create the label */
3098 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3099 return createLabel(newSymbol(defLbl,0),stmnt);
3102 /*-----------------------------------------------------------------*/
3103 /* createIf - creates the parsetree for the if statement */
3104 /*-----------------------------------------------------------------*/
3105 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3107 static int Lblnum = 0 ;
3109 symbol *ifTrue , *ifFalse, *ifEnd ;
3111 /* if neither exists */
3112 if (! elseBody && !ifBody)
3115 /* create the labels */
3116 sprintf (buffer,"_iffalse_%d",Lblnum);
3117 ifFalse = newSymbol (buffer,NestLevel);
3118 /* if no else body then end == false */
3122 sprintf (buffer,"_ifend_%d",Lblnum);
3123 ifEnd = newSymbol (buffer,NestLevel);
3126 sprintf (buffer,"_iftrue_%d",Lblnum);
3127 ifTrue = newSymbol (buffer,NestLevel);
3131 /* attach the ifTrue label to the top of it body */
3132 ifBody = createLabel(ifTrue,ifBody);
3133 /* attach a goto end to the ifBody if else is present */
3135 ifBody = newNode(NULLOP,ifBody,
3137 newAst_VALUE(symbolVal(ifEnd)),
3139 /* put the elseLabel on the else body */
3140 elseBody = createLabel (ifFalse,elseBody);
3141 /* out the end at the end of the body */
3142 elseBody = newNode(NULLOP,
3144 createLabel(ifEnd,NULL));
3147 ifBody = newNode(NULLOP,ifBody,
3148 createLabel(ifFalse,NULL));
3150 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3151 if (IS_IFX(condAst))
3154 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3156 return newNode(NULLOP,ifTree,
3157 newNode(NULLOP,ifBody,elseBody));
3161 /*-----------------------------------------------------------------*/
3162 /* createDo - creates parse tree for do */
3165 /* _docontinue_n: */
3166 /* condition_expression +-> trueLabel -> _dobody_n */
3168 /* +-> falseLabel-> _dobreak_n */
3170 /*-----------------------------------------------------------------*/
3171 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3172 symbol *falseLabel, ast *condAst, ast *doBody )
3177 /* if the body does not exist then it is simple */
3179 condAst = backPatchLabels(condAst,continueLabel,NULL);
3180 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3181 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3182 doTree->trueLabel = continueLabel ;
3183 doTree->falseLabel= NULL ;
3187 /* otherwise we have a body */
3188 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3190 /* attach the body label to the top */
3191 doBody = createLabel(trueLabel,doBody);
3192 /* attach the continue label to end of body */
3193 doBody = newNode(NULLOP, doBody,
3194 createLabel(continueLabel,NULL));
3196 /* now put the break label at the end */
3197 if (IS_IFX(condAst))
3200 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3202 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3204 /* putting it together */
3205 return newNode(NULLOP,doBody,doTree);
3208 /*-----------------------------------------------------------------*/
3209 /* createFor - creates parse tree for 'for' statement */
3212 /* condExpr +-> trueLabel -> _forbody_n */
3214 /* +-> falseLabel-> _forbreak_n */
3217 /* _forcontinue_n: */
3219 /* goto _forcond_n ; */
3221 /*-----------------------------------------------------------------*/
3222 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3223 symbol *falseLabel,symbol *condLabel ,
3224 ast *initExpr, ast *condExpr, ast *loopExpr,
3229 /* if loopexpression not present then we can generate it */
3230 /* the same way as a while */
3232 return newNode(NULLOP,initExpr,
3233 createWhile (trueLabel, continueLabel,
3234 falseLabel,condExpr, forBody ));
3235 /* vanilla for statement */
3236 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3238 if (condExpr && !IS_IFX(condExpr))
3239 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3242 /* attach condition label to condition */
3243 condExpr = createLabel(condLabel,condExpr);
3245 /* attach body label to body */
3246 forBody = createLabel(trueLabel,forBody);
3248 /* attach continue to forLoop expression & attach */
3249 /* goto the forcond @ and of loopExpression */
3250 loopExpr = createLabel(continueLabel,
3254 newAst_VALUE(symbolVal(condLabel)),
3256 /* now start putting them together */
3257 forTree = newNode(NULLOP,initExpr,condExpr);
3258 forTree = newNode(NULLOP,forTree,forBody);
3259 forTree = newNode(NULLOP,forTree,loopExpr);
3260 /* finally add the break label */
3261 forTree = newNode(NULLOP,forTree,
3262 createLabel(falseLabel,NULL));
3266 /*-----------------------------------------------------------------*/
3267 /* createWhile - creates parse tree for while statement */
3268 /* the while statement will be created as follows */
3270 /* _while_continue_n: */
3271 /* condition_expression +-> trueLabel -> _while_boby_n */
3273 /* +-> falseLabel -> _while_break_n*/
3274 /* _while_body_n: */
3276 /* goto _while_continue_n */
3277 /* _while_break_n: */
3278 /*-----------------------------------------------------------------*/
3279 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3280 symbol *falseLabel,ast *condExpr, ast *whileBody )
3284 /* put the continue label */
3285 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3286 condExpr = createLabel(continueLabel,condExpr);
3287 condExpr->lineno = 0;
3289 /* put the body label in front of the body */
3290 whileBody = createLabel(trueLabel,whileBody);
3291 whileBody->lineno = 0;
3292 /* put a jump to continue at the end of the body */
3293 /* and put break label at the end of the body */
3294 whileBody = newNode(NULLOP,
3297 newAst_VALUE(symbolVal(continueLabel)),
3298 createLabel(falseLabel,NULL)));
3300 /* put it all together */
3301 if ( IS_IFX(condExpr) )
3302 whileTree = condExpr ;
3304 whileTree = newNode (IFX, condExpr,NULL );
3305 /* put the true & false labels in place */
3306 whileTree->trueLabel = trueLabel ;
3307 whileTree->falseLabel= falseLabel;
3310 return newNode(NULLOP,whileTree,whileBody );
3313 /*-----------------------------------------------------------------*/
3314 /* optimizeGetHbit - get highest order bit of the expression */
3315 /*-----------------------------------------------------------------*/
3316 ast *optimizeGetHbit (ast *tree)
3319 /* if this is not a bit and */
3320 if (!IS_BITAND(tree))
3323 /* will look for tree of the form
3324 ( expr >> ((sizeof expr) -1) ) & 1 */
3325 if (!IS_AST_LIT_VALUE(tree->right))
3328 if (AST_LIT_VALUE(tree->right) != 1)
3331 if (!IS_RIGHT_OP(tree->left))
3334 if (!IS_AST_LIT_VALUE(tree->left->right))
3337 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3338 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3341 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3345 /*-----------------------------------------------------------------*/
3346 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3347 /*-----------------------------------------------------------------*/
3348 ast *optimizeRRCRLC ( ast *root )
3350 /* will look for trees of the form
3351 (?expr << 1) | (?expr >> 7) or
3352 (?expr >> 7) | (?expr << 1) will make that
3353 into a RLC : operation ..
3355 (?expr >> 1) | (?expr << 7) or
3356 (?expr << 7) | (?expr >> 1) will make that
3357 into a RRC operation
3358 note : by 7 I mean (number of bits required to hold the
3360 /* if the root operations is not a | operation the not */
3361 if (!IS_BITOR(root))
3364 /* I have to think of a better way to match patterns this sucks */
3365 /* that aside let start looking for the first case : I use a the
3366 negative check a lot to improve the efficiency */
3367 /* (?expr << 1) | (?expr >> 7) */
3368 if (IS_LEFT_OP(root->left) &&
3369 IS_RIGHT_OP(root->right) ) {
3371 if (!SPEC_USIGN(TETYPE(root->left->left)))
3374 if (!IS_AST_LIT_VALUE(root->left->right) ||
3375 !IS_AST_LIT_VALUE(root->right->right))
3378 /* make sure it is the same expression */
3379 if (!isAstEqual(root->left->left,
3383 if (AST_LIT_VALUE(root->left->right) != 1 )
3386 if (AST_LIT_VALUE(root->right->right) !=
3387 (getSize(TTYPE(root->left->left))*8 - 1))
3390 /* whew got the first case : create the AST */
3391 return newNode(RLC,root->left->left,NULL);
3395 /* check for second case */
3396 /* (?expr >> 7) | (?expr << 1) */
3397 if (IS_LEFT_OP(root->right) &&
3398 IS_RIGHT_OP(root->left) ) {
3400 if (!SPEC_USIGN(TETYPE(root->left->left)))
3403 if (!IS_AST_LIT_VALUE(root->left->right) ||
3404 !IS_AST_LIT_VALUE(root->right->right))
3407 /* make sure it is the same symbol */
3408 if (!isAstEqual(root->left->left,
3412 if (AST_LIT_VALUE(root->right->right) != 1 )
3415 if (AST_LIT_VALUE(root->left->right) !=
3416 (getSize(TTYPE(root->left->left))*8 - 1))
3419 /* whew got the first case : create the AST */
3420 return newNode(RLC,root->left->left,NULL);
3425 /* third case for RRC */
3426 /* (?symbol >> 1) | (?symbol << 7) */
3427 if (IS_LEFT_OP(root->right) &&
3428 IS_RIGHT_OP(root->left) ) {
3430 if (!SPEC_USIGN(TETYPE(root->left->left)))
3433 if (!IS_AST_LIT_VALUE(root->left->right) ||
3434 !IS_AST_LIT_VALUE(root->right->right))
3437 /* make sure it is the same symbol */
3438 if (!isAstEqual(root->left->left,
3442 if (AST_LIT_VALUE(root->left->right) != 1 )
3445 if (AST_LIT_VALUE(root->right->right) !=
3446 (getSize(TTYPE(root->left->left))*8 - 1))
3449 /* whew got the first case : create the AST */
3450 return newNode(RRC,root->left->left,NULL);
3454 /* fourth and last case for now */
3455 /* (?symbol << 7) | (?symbol >> 1) */
3456 if (IS_RIGHT_OP(root->right) &&
3457 IS_LEFT_OP(root->left) ) {
3459 if (!SPEC_USIGN(TETYPE(root->left->left)))
3462 if (!IS_AST_LIT_VALUE(root->left->right) ||
3463 !IS_AST_LIT_VALUE(root->right->right))
3466 /* make sure it is the same symbol */
3467 if (!isAstEqual(root->left->left,
3471 if (AST_LIT_VALUE(root->right->right) != 1 )
3474 if (AST_LIT_VALUE(root->left->right) !=
3475 (getSize(TTYPE(root->left->left))*8 - 1))
3478 /* whew got the first case : create the AST */
3479 return newNode(RRC,root->left->left,NULL);
3483 /* not found return root */
3487 /*-----------------------------------------------------------------*/
3488 /* optimizeCompare - otimizes compares for bit variables */
3489 /*-----------------------------------------------------------------*/
3490 ast *optimizeCompare ( ast *root )
3492 ast *optExpr = NULL;
3495 unsigned int litValue ;
3497 /* if nothing then return nothing */
3501 /* if not a compare op then do leaves */
3502 if (!IS_COMPARE_OP(root)) {
3503 root->left = optimizeCompare (root->left);
3504 root->right= optimizeCompare (root->right);
3508 /* if left & right are the same then depending
3509 of the operation do */
3510 if (isAstEqual(root->left,root->right)) {
3511 switch (root->opval.op) {
3515 optExpr = newAst_VALUE(constVal("0"));
3520 optExpr = newAst_VALUE(constVal("1"));
3524 return decorateType(optExpr);
3527 vleft = (root->left->type == EX_VALUE ?
3528 root->left->opval.val : NULL );
3530 vright = (root->right->type == EX_VALUE ?
3531 root->right->opval.val : NULL);
3533 /* if left is a BITVAR in BITSPACE */
3534 /* and right is a LITERAL then opt-*/
3535 /* imize else do nothing */
3536 if (vleft && vright &&
3537 IS_BITVAR(vleft->etype) &&
3538 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3539 IS_LITERAL(vright->etype)) {
3541 /* if right side > 1 then comparison may never succeed */
3542 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3543 werror(W_BAD_COMPARE);
3548 switch (root->opval.op) {
3549 case '>' : /* bit value greater than 1 cannot be */
3550 werror(W_BAD_COMPARE);
3554 case '<' : /* bit value < 1 means 0 */
3556 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3559 case LE_OP : /* bit value <= 1 means no check */
3560 optExpr = newAst_VALUE(vright);
3563 case GE_OP : /* bit value >= 1 means only check for = */
3565 optExpr = newAst_VALUE(vleft);
3568 } else { /* literal is zero */
3569 switch (root->opval.op) {
3570 case '<' : /* bit value < 0 cannot be */
3571 werror(W_BAD_COMPARE);
3575 case '>' : /* bit value > 0 means 1 */
3577 optExpr = newAst_VALUE(vleft);
3580 case LE_OP : /* bit value <= 0 means no check */
3581 case GE_OP : /* bit value >= 0 means no check */
3582 werror(W_BAD_COMPARE);
3586 case EQ_OP : /* bit == 0 means ! of bit */
3587 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3591 return decorateType(resolveSymbols(optExpr));
3592 } /* end-of-if of BITVAR */
3597 /*-----------------------------------------------------------------*/
3598 /* addSymToBlock : adds the symbol to the first block we find */
3599 /*-----------------------------------------------------------------*/
3600 void addSymToBlock (symbol *sym, ast *tree)
3602 /* reached end of tree or a leaf */
3603 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3607 if (IS_AST_OP(tree) &&
3608 tree->opval.op == BLOCK ) {
3610 symbol *lsym = copySymbol(sym);
3612 lsym->next = AST_VALUES(tree,sym);
3613 AST_VALUES(tree,sym) = lsym ;
3617 addSymToBlock(sym,tree->left);
3618 addSymToBlock(sym,tree->right);
3621 /*-----------------------------------------------------------------*/
3622 /* processRegParms - do processing for register parameters */
3623 /*-----------------------------------------------------------------*/
3624 static void processRegParms (value *args, ast *body)
3627 if (IS_REGPARM(args->etype))
3628 addSymToBlock(args->sym,body);
3633 /*-----------------------------------------------------------------*/
3634 /* resetParmKey - resets the operandkeys for the symbols */
3635 /*-----------------------------------------------------------------*/
3636 DEFSETFUNC(resetParmKey)
3647 /*-----------------------------------------------------------------*/
3648 /* createFunction - This is the key node that calls the iCode for */
3649 /* generating the code for a function. Note code */
3650 /* is generated function by function, later when */
3651 /* add inter-procedural analysis this will change */
3652 /*-----------------------------------------------------------------*/
3653 ast *createFunction (symbol *name, ast *body )
3659 iCode *piCode = NULL;
3661 /* if check function return 0 then some problem */
3662 if (checkFunction (name) == 0)
3665 /* create a dummy block if none exists */
3667 body = newNode(BLOCK,NULL,NULL);
3671 /* check if the function name already in the symbol table */
3672 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3674 /* special case for compiler defined functions
3675 we need to add the name to the publics list : this
3676 actually means we are now compiling the compiler
3679 addSet(&publics,name);
3684 allocVariables(name);
3686 name->lastLine = yylineno;
3688 processFuncArgs(currFunc,0);
3690 /* set the stack pointer */
3691 /* PENDING: check this for the mcs51 */
3692 stackPtr = -port->stack.direction * port->stack.call_overhead;
3693 if (IS_ISR(name->etype))
3694 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3695 if (IS_RENT(name->etype) || options.stackAuto)
3696 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3698 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3700 fetype = getSpec(name->type); /* get the specifier for the function */
3701 /* if this is a reentrant function then */
3702 if (IS_RENT(fetype))
3705 allocParms (name->args); /* allocate the parameters */
3707 /* do processing for parameters that are passed in registers */
3708 processRegParms (name->args,body);
3710 /* set the stack pointer */
3714 /* allocate & autoinit the block variables */
3715 processBlockVars (body, &stack,ALLOCATE);
3717 /* save the stack information */
3718 if (options.useXstack)
3719 name->xstack = SPEC_STAK(fetype) = stack;
3721 name->stack = SPEC_STAK(fetype) = stack;
3723 /* name needs to be mangled */
3724 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3726 body = resolveSymbols(body); /* resolve the symbols */
3727 body = decorateType (body); /* propagateType & do semantic checks */
3729 ex = newAst_VALUE(symbolVal(name)); /* create name */
3730 ex = newNode (FUNCTION,ex,body);
3731 ex->values.args = name->args ;
3734 werror(E_FUNC_NO_CODE,name->name);
3738 /* create the node & generate intermediate code */
3739 codeOutFile = code->oFile;
3740 piCode = iCodeFromAst(ex);
3743 werror(E_FUNC_NO_CODE,name->name);
3747 eBBlockFromiCode(piCode);
3749 /* if there are any statics then do them */
3751 codeOutFile = statsg->oFile;
3752 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3758 /* dealloc the block variables */
3759 processBlockVars(body, &stack,DEALLOCATE);
3760 /* deallocate paramaters */
3761 deallocParms(name->args);
3763 if (IS_RENT(fetype))
3766 /* we are done freeup memory & cleanup */
3771 addSet(&operKeyReset,name);
3772 applyToSet(operKeyReset,resetParmKey);
3774 if (options.debug && !options.nodebug)
3775 cdbStructBlock(1,cdbFile);
3777 cleanUpLevel(LabelTab,0);
3778 cleanUpBlock(StructTab,1);
3779 cleanUpBlock(TypedefTab,1);
3781 xstack->syms = NULL;
3782 istack->syms = NULL;