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 /*-----------------------------------------------------------------*/
1510 /* decorateType - compute type for this tree also does type cheking*/
1511 /* this is done bottom up, since type have to flow upwards*/
1512 /* it also does constant folding, and paramater checking */
1513 /*-----------------------------------------------------------------*/
1514 ast *decorateType (ast *tree)
1522 /* if already has type then do nothing */
1523 if ( tree->decorated )
1526 tree->decorated = 1;
1528 /* print the line */
1529 /* if not block & function */
1530 if ( tree->type == EX_OP &&
1531 ( tree->opval.op != FUNCTION &&
1532 tree->opval.op != BLOCK &&
1533 tree->opval.op != NULLOP )) {
1534 filename = tree->filename ;
1535 lineno = tree->lineno ;
1538 /* if any child is an error | this one is an error do nothing */
1539 if ( tree->isError ||
1540 ( tree->left && tree->left->isError) ||
1541 ( tree->right && tree->right->isError ))
1544 /*------------------------------------------------------------------*/
1545 /*----------------------------*/
1546 /* leaf has been reached */
1547 /*----------------------------*/
1548 /* if this is of type value */
1549 /* just get the type */
1550 if ( tree->type == EX_VALUE ) {
1552 if ( IS_LITERAL(tree->opval.val->etype) ) {
1554 /* if this is a character array then declare it */
1555 if (IS_ARRAY(tree->opval.val->type))
1556 tree->opval.val = stringToSymbol(tree->opval.val);
1558 /* otherwise just copy the type information */
1559 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1560 if (funcInChain(tree->opval.val->type)) {
1561 tree->hasVargs = tree->opval.val->sym->hasVargs;
1562 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1567 if ( tree->opval.val->sym ) {
1568 /* if the undefined flag is set then give error message */
1569 if (tree->opval.val->sym->undefined ) {
1570 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1572 TTYPE(tree) = TETYPE(tree) =
1573 tree->opval.val->type = tree->opval.val->sym->type =
1574 tree->opval.val->etype = tree->opval.val->sym->etype =
1575 copyLinkChain(INTTYPE);
1579 /* if impilicit i.e. struct/union member then no type */
1580 if (tree->opval.val->sym->implicit )
1581 TTYPE(tree) = TETYPE(tree) = NULL ;
1585 /* else copy the type */
1586 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1588 /* and mark it as referenced */
1589 tree->opval.val->sym->isref = 1;
1590 /* if this is of type function or function pointer */
1591 if (funcInChain(tree->opval.val->type)) {
1592 tree->hasVargs = tree->opval.val->sym->hasVargs;
1593 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1603 /* if type link for the case of cast */
1604 if ( tree->type == EX_LINK ) {
1605 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1612 dtl = decorateType (tree->left);
1613 dtr = decorateType (tree->right);
1615 /* this is to take care of situations
1616 when the tree gets rewritten */
1617 if (dtl != tree->left)
1619 if (dtr != tree->right)
1623 /* depending on type of operator do */
1625 switch (tree->opval.op) {
1626 /*------------------------------------------------------------------*/
1627 /*----------------------------*/
1629 /*----------------------------*/
1632 /* determine which is the array & which the index */
1633 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1635 ast *tempTree = tree->left ;
1636 tree->left = tree->right ;
1637 tree->right= tempTree ;
1640 /* first check if this is a array or a pointer */
1641 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1642 werror(E_NEED_ARRAY_PTR,"[]");
1643 goto errorTreeReturn ;
1646 /* check if the type of the idx */
1647 if (!IS_INTEGRAL(RTYPE(tree))) {
1648 werror(E_IDX_NOT_INT);
1649 goto errorTreeReturn ;
1652 /* if the left is an rvalue then error */
1654 werror(E_LVALUE_REQUIRED,"array access");
1655 goto errorTreeReturn ;
1658 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1661 /*------------------------------------------------------------------*/
1662 /*----------------------------*/
1664 /*----------------------------*/
1666 /* if this is not a structure */
1667 if (!IS_STRUCT(LTYPE(tree))) {
1668 werror(E_STRUCT_UNION,".");
1669 goto errorTreeReturn ;
1671 TTYPE(tree) = structElemType (LTYPE(tree),
1672 (tree->right->type == EX_VALUE ?
1673 tree->right->opval.val : NULL ),&tree->args);
1674 TETYPE(tree) = getSpec(TTYPE(tree));
1677 /*------------------------------------------------------------------*/
1678 /*----------------------------*/
1679 /* struct/union pointer */
1680 /*----------------------------*/
1682 /* if not pointer to a structure */
1683 if (!IS_PTR(LTYPE(tree))) {
1685 goto errorTreeReturn ;
1688 if (!IS_STRUCT(LTYPE(tree)->next)) {
1689 werror(E_STRUCT_UNION,"->");
1690 goto errorTreeReturn ;
1693 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1694 (tree->right->type == EX_VALUE ?
1695 tree->right->opval.val : NULL ),&tree->args);
1696 TETYPE(tree) = getSpec(TTYPE(tree));
1699 /*------------------------------------------------------------------*/
1700 /*----------------------------*/
1701 /* ++/-- operation */
1702 /*----------------------------*/
1703 case INC_OP: /* incerement operator unary so left only */
1706 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1707 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1708 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1709 werror(E_CODE_WRITE,"++/--");
1718 /*------------------------------------------------------------------*/
1719 /*----------------------------*/
1721 /*----------------------------*/
1722 case '&': /* can be unary */
1723 /* if right is NULL then unary operation */
1724 if ( tree->right ) /* not an unary operation */ {
1726 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1727 werror(E_BITWISE_OP);
1728 werror(E_CONTINUE,"left & right types are ");
1729 printTypeChain(LTYPE(tree),stderr);
1730 fprintf(stderr,",");
1731 printTypeChain(RTYPE(tree),stderr);
1732 fprintf(stderr,"\n");
1733 goto errorTreeReturn ;
1736 /* if they are both literal */
1737 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1738 tree->type = EX_VALUE ;
1739 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1740 valFromType(RETYPE(tree)),'&');
1742 tree->right = tree->left = NULL;
1743 TETYPE(tree) = tree->opval.val->etype ;
1744 TTYPE(tree) = tree->opval.val->type;
1748 /* see if this is a GETHBIT operation if yes
1751 ast *otree = optimizeGetHbit(tree);
1754 return decorateType(otree);
1757 /* if right or left is literal then result of that type*/
1758 if (IS_LITERAL(RTYPE(tree))) {
1760 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1761 TETYPE(tree) = getSpec(TTYPE(tree));
1762 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1765 if (IS_LITERAL(LTYPE(tree))) {
1766 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1767 TETYPE(tree) = getSpec(TTYPE(tree));
1768 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1773 computeType (LTYPE(tree), RTYPE(tree));
1774 TETYPE(tree) = getSpec(TTYPE(tree));
1777 LRVAL(tree) = RRVAL(tree) = 1;
1781 /*------------------------------------------------------------------*/
1782 /*----------------------------*/
1784 /*----------------------------*/
1786 p->class = DECLARATOR;
1787 /* if bit field then error */
1788 if (IS_BITVAR(tree->left->etype)) {
1789 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1790 goto errorTreeReturn ;
1793 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1794 werror (E_ILLEGAL_ADDR,"address of register variable");
1795 goto errorTreeReturn;
1798 if (IS_FUNC(LTYPE(tree))) {
1799 werror(E_ILLEGAL_ADDR,"address of function");
1800 goto errorTreeReturn ;
1804 werror(E_LVALUE_REQUIRED,"address of");
1805 goto errorTreeReturn ;
1807 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1808 DCL_TYPE(p) = CPOINTER ;
1809 DCL_PTR_CONST(p) = port->mem.code_ro;
1812 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1813 DCL_TYPE(p) = FPOINTER;
1815 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1816 DCL_TYPE(p) = PPOINTER ;
1818 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1819 DCL_TYPE(p) = IPOINTER ;
1821 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1822 DCL_TYPE(p) = EEPPOINTER ;
1824 DCL_TYPE(p) = POINTER ;
1826 if (IS_AST_SYM_VALUE(tree->left)) {
1827 AST_SYMBOL(tree->left)->addrtaken = 1;
1828 AST_SYMBOL(tree->left)->allocreq = 1;
1831 p->next = LTYPE(tree);
1833 TETYPE(tree) = getSpec(TTYPE(tree));
1834 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1835 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1840 /*------------------------------------------------------------------*/
1841 /*----------------------------*/
1843 /*----------------------------*/
1845 /* if the rewrite succeeds then don't go any furthur */
1847 ast *wtree = optimizeRRCRLC ( tree );
1849 return decorateType(wtree) ;
1851 /*------------------------------------------------------------------*/
1852 /*----------------------------*/
1854 /*----------------------------*/
1856 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1857 werror(E_BITWISE_OP);
1858 werror(E_CONTINUE,"left & right types are ");
1859 printTypeChain(LTYPE(tree),stderr);
1860 fprintf(stderr,",");
1861 printTypeChain(RTYPE(tree),stderr);
1862 fprintf(stderr,"\n");
1863 goto errorTreeReturn ;
1866 /* if they are both literal then */
1867 /* rewrite the tree */
1868 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1869 tree->type = EX_VALUE ;
1870 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1871 valFromType(RETYPE(tree)),
1873 tree->right = tree->left = NULL;
1874 TETYPE(tree) = tree->opval.val->etype;
1875 TTYPE(tree) = tree->opval.val->type;
1878 LRVAL(tree) = RRVAL(tree) = 1;
1879 TETYPE(tree) = getSpec (TTYPE(tree) =
1880 computeType(LTYPE(tree),
1883 /*------------------------------------------------------------------*/
1884 /*----------------------------*/
1886 /*----------------------------*/
1888 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1889 werror(E_INVALID_OP,"divide");
1890 goto errorTreeReturn ;
1892 /* if they are both literal then */
1893 /* rewrite the tree */
1894 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1895 tree->type = EX_VALUE ;
1896 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
1897 valFromType(RETYPE(tree)));
1898 tree->right = tree->left = NULL;
1899 TETYPE(tree) = getSpec(TTYPE(tree) =
1900 tree->opval.val->type);
1903 LRVAL(tree) = RRVAL(tree) = 1;
1904 TETYPE(tree) = getSpec (TTYPE(tree) =
1905 computeType(LTYPE(tree),
1909 /*------------------------------------------------------------------*/
1910 /*----------------------------*/
1912 /*----------------------------*/
1914 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1915 werror(E_BITWISE_OP);
1916 werror(E_CONTINUE,"left & right types are ");
1917 printTypeChain(LTYPE(tree),stderr);
1918 fprintf(stderr,",");
1919 printTypeChain(RTYPE(tree),stderr);
1920 fprintf(stderr,"\n");
1921 goto errorTreeReturn ;
1923 /* if they are both literal then */
1924 /* rewrite the tree */
1925 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1926 tree->type = EX_VALUE ;
1927 tree->opval.val = valMod (valFromType(LETYPE(tree)),
1928 valFromType(RETYPE(tree)));
1929 tree->right = tree->left = NULL;
1930 TETYPE(tree) = getSpec(TTYPE(tree) =
1931 tree->opval.val->type);
1934 LRVAL(tree) = RRVAL(tree) = 1;
1935 TETYPE(tree) = getSpec (TTYPE(tree) =
1936 computeType(LTYPE(tree),
1940 /*------------------------------------------------------------------*/
1941 /*----------------------------*/
1942 /* address dereference */
1943 /*----------------------------*/
1944 case '*': /* can be unary : if right is null then unary operation */
1945 if ( ! tree->right ) {
1946 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
1948 goto errorTreeReturn ;
1952 werror(E_LVALUE_REQUIRED,"pointer deref");
1953 goto errorTreeReturn ;
1955 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
1956 LTYPE(tree)->next : NULL );
1957 TETYPE(tree) = getSpec(TTYPE(tree));
1958 tree->args = tree->left->args ;
1959 tree->hasVargs = tree->left->hasVargs ;
1960 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
1964 /*------------------------------------------------------------------*/
1965 /*----------------------------*/
1966 /* multiplication */
1967 /*----------------------------*/
1968 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1969 werror(E_INVALID_OP,"multiplication");
1970 goto errorTreeReturn ;
1973 /* if they are both literal then */
1974 /* rewrite the tree */
1975 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1976 tree->type = EX_VALUE ;
1977 tree->opval.val = valMult (valFromType(LETYPE(tree)),
1978 valFromType(RETYPE(tree)));
1979 tree->right = tree->left = NULL;
1980 TETYPE(tree) = getSpec(TTYPE(tree) =
1981 tree->opval.val->type);
1985 /* if left is a literal exchange left & right */
1986 if (IS_LITERAL(LTYPE(tree))) {
1987 ast *tTree = tree->left ;
1988 tree->left = tree->right ;
1989 tree->right= tTree ;
1992 LRVAL(tree) = RRVAL(tree) = 1;
1993 TETYPE(tree) = getSpec (TTYPE(tree) =
1994 computeType(LTYPE(tree),
1998 /*------------------------------------------------------------------*/
1999 /*----------------------------*/
2000 /* unary '+' operator */
2001 /*----------------------------*/
2004 if ( ! tree->right ) {
2005 if (!IS_INTEGRAL(LTYPE(tree))) {
2006 werror(E_UNARY_OP,'+');
2007 goto errorTreeReturn ;
2010 /* if left is a literal then do it */
2011 if (IS_LITERAL(LTYPE(tree))) {
2012 tree->type = EX_VALUE ;
2013 tree->opval.val = valFromType(LETYPE(tree));
2015 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2019 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2023 /*------------------------------------------------------------------*/
2024 /*----------------------------*/
2026 /*----------------------------*/
2028 /* this is not a unary operation */
2029 /* if both pointers then problem */
2030 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2031 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2032 werror(E_PTR_PLUS_PTR);
2033 goto errorTreeReturn ;
2036 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2037 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2038 werror(E_PLUS_INVALID,"+");
2039 goto errorTreeReturn ;
2042 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2043 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2044 werror(E_PLUS_INVALID,"+");
2045 goto errorTreeReturn;
2047 /* if they are both literal then */
2048 /* rewrite the tree */
2049 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2050 tree->type = EX_VALUE ;
2051 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2052 valFromType(RETYPE(tree)));
2053 tree->right = tree->left = NULL;
2054 TETYPE(tree) = getSpec(TTYPE(tree) =
2055 tree->opval.val->type);
2059 /* if the right is a pointer or left is a literal
2060 xchange left & right */
2061 if (IS_ARRAY(RTYPE(tree)) ||
2062 IS_PTR(RTYPE(tree)) ||
2063 IS_LITERAL(LTYPE(tree))) {
2064 ast *tTree = tree->left ;
2065 tree->left = tree->right ;
2066 tree->right= tTree ;
2069 LRVAL(tree) = RRVAL(tree) = 1;
2070 /* if the left is a pointer */
2071 if (IS_PTR(LTYPE(tree)))
2072 TETYPE(tree) = getSpec(TTYPE(tree) =
2075 TETYPE(tree) = getSpec(TTYPE(tree) =
2076 computeType(LTYPE(tree),
2080 /*------------------------------------------------------------------*/
2081 /*----------------------------*/
2083 /*----------------------------*/
2084 case '-' : /* can be unary */
2085 /* if right is null then unary */
2086 if ( ! tree->right ) {
2088 if (!IS_ARITHMETIC(LTYPE(tree))) {
2089 werror(E_UNARY_OP,tree->opval.op);
2090 goto errorTreeReturn ;
2093 /* if left is a literal then do it */
2094 if (IS_LITERAL(LTYPE(tree))) {
2095 tree->type = EX_VALUE ;
2096 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2098 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2102 TTYPE(tree) = LTYPE(tree);
2106 /*------------------------------------------------------------------*/
2107 /*----------------------------*/
2109 /*----------------------------*/
2111 if (!(IS_PTR(LTYPE(tree)) ||
2112 IS_ARRAY(LTYPE(tree)) ||
2113 IS_ARITHMETIC(LTYPE(tree)))) {
2114 werror(E_PLUS_INVALID,"-");
2115 goto errorTreeReturn ;
2118 if (!(IS_PTR(RTYPE(tree)) ||
2119 IS_ARRAY(RTYPE(tree)) ||
2120 IS_ARITHMETIC(RTYPE(tree)))) {
2121 werror(E_PLUS_INVALID,"-");
2122 goto errorTreeReturn ;
2125 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2126 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2127 IS_INTEGRAL(RTYPE(tree))) ) {
2128 werror(E_PLUS_INVALID,"-");
2129 goto errorTreeReturn ;
2132 /* if they are both literal then */
2133 /* rewrite the tree */
2134 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2135 tree->type = EX_VALUE ;
2136 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2137 valFromType(RETYPE(tree)));
2138 tree->right = tree->left = NULL;
2139 TETYPE(tree) = getSpec(TTYPE(tree) =
2140 tree->opval.val->type);
2144 /* if the left & right are equal then zero */
2145 if (isAstEqual(tree->left,tree->right)) {
2146 tree->type = EX_VALUE;
2147 tree->left = tree->right = NULL;
2148 tree->opval.val = constVal("0");
2149 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2153 /* if both of them are pointers or arrays then */
2154 /* the result is going to be an integer */
2155 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2156 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2157 TETYPE(tree) = TTYPE(tree) = newIntLink();
2159 /* if only the left is a pointer */
2160 /* then result is a pointer */
2161 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2162 TETYPE(tree) = getSpec(TTYPE(tree) =
2165 TETYPE(tree) = getSpec (TTYPE(tree) =
2166 computeType(LTYPE(tree),
2168 LRVAL(tree) = RRVAL(tree) = 1;
2171 /*------------------------------------------------------------------*/
2172 /*----------------------------*/
2174 /*----------------------------*/
2176 /* can be only integral type */
2177 if (!IS_INTEGRAL(LTYPE(tree))) {
2178 werror(E_UNARY_OP,tree->opval.op);
2179 goto errorTreeReturn ;
2182 /* if left is a literal then do it */
2183 if (IS_LITERAL(LTYPE(tree))) {
2184 tree->type = EX_VALUE ;
2185 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2187 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2191 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2194 /*------------------------------------------------------------------*/
2195 /*----------------------------*/
2197 /*----------------------------*/
2199 /* can be pointer */
2200 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2201 !IS_PTR(LTYPE(tree)) &&
2202 !IS_ARRAY(LTYPE(tree))) {
2203 werror(E_UNARY_OP,tree->opval.op);
2204 goto errorTreeReturn ;
2207 /* if left is a literal then do it */
2208 if (IS_LITERAL(LTYPE(tree))) {
2209 tree->type = EX_VALUE ;
2210 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2212 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2216 TTYPE(tree) = TETYPE(tree) = newCharLink();
2219 /*------------------------------------------------------------------*/
2220 /*----------------------------*/
2222 /*----------------------------*/
2225 TTYPE(tree) = LTYPE(tree);
2226 TETYPE(tree) = LETYPE(tree);
2230 TTYPE(tree) = TETYPE(tree) = newCharLink();
2235 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2236 werror(E_SHIFT_OP_INVALID);
2237 werror(E_CONTINUE,"left & right types are ");
2238 printTypeChain(LTYPE(tree),stderr);
2239 fprintf(stderr,",");
2240 printTypeChain(RTYPE(tree),stderr);
2241 fprintf(stderr,"\n");
2242 goto errorTreeReturn ;
2245 /* if they are both literal then */
2246 /* rewrite the tree */
2247 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2248 tree->type = EX_VALUE ;
2249 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2250 valFromType(RETYPE(tree)),
2251 (tree->opval.op == LEFT_OP ? 1 : 0));
2252 tree->right = tree->left = NULL;
2253 TETYPE(tree) = getSpec(TTYPE(tree) =
2254 tree->opval.val->type);
2257 /* if only the right side is a literal & we are
2258 shifting more than size of the left operand then zero */
2259 if (IS_LITERAL(RTYPE(tree)) &&
2260 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2261 (getSize(LTYPE(tree))*8)) {
2262 werror(W_SHIFT_CHANGED,
2263 (tree->opval.op == LEFT_OP ? "left" : "right"));
2264 tree->type = EX_VALUE;
2265 tree->left = tree->right = NULL;
2266 tree->opval.val = constVal("0");
2267 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2270 LRVAL(tree) = RRVAL(tree) = 1;
2271 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2272 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2274 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2278 /*------------------------------------------------------------------*/
2279 /*----------------------------*/
2281 /*----------------------------*/
2282 case CAST: /* change the type */
2283 /* cannot cast to an aggregate type */
2284 if (IS_AGGREGATE(LTYPE(tree))) {
2285 werror(E_CAST_ILLEGAL);
2286 goto errorTreeReturn ;
2289 /* if the right is a literal replace the tree */
2290 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2291 tree->type = EX_VALUE ;
2293 valCastLiteral(LTYPE(tree),
2294 floatFromVal(valFromType(RETYPE(tree))));
2297 TTYPE(tree) = tree->opval.val->type;
2300 TTYPE(tree) = LTYPE(tree);
2304 TETYPE(tree) = getSpec(TTYPE(tree));
2308 /*------------------------------------------------------------------*/
2309 /*----------------------------*/
2310 /* logical &&, || */
2311 /*----------------------------*/
2314 /* each must me arithmetic type or be a pointer */
2315 if (!IS_PTR(LTYPE(tree)) &&
2316 !IS_ARRAY(LTYPE(tree)) &&
2317 !IS_INTEGRAL(LTYPE(tree))) {
2318 werror(E_COMPARE_OP);
2319 goto errorTreeReturn ;
2322 if (!IS_PTR(RTYPE(tree)) &&
2323 !IS_ARRAY(RTYPE(tree)) &&
2324 !IS_INTEGRAL(RTYPE(tree))) {
2325 werror(E_COMPARE_OP);
2326 goto errorTreeReturn ;
2328 /* if they are both literal then */
2329 /* rewrite the tree */
2330 if (IS_LITERAL(RTYPE(tree)) &&
2331 IS_LITERAL(LTYPE(tree))) {
2332 tree->type = EX_VALUE ;
2333 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2334 valFromType(RETYPE(tree)),
2336 tree->right = tree->left = NULL;
2337 TETYPE(tree) = getSpec(TTYPE(tree) =
2338 tree->opval.val->type);
2341 LRVAL(tree) = RRVAL(tree) = 1;
2342 TTYPE(tree) = TETYPE(tree) = newCharLink();
2345 /*------------------------------------------------------------------*/
2346 /*----------------------------*/
2347 /* comparison operators */
2348 /*----------------------------*/
2356 ast *lt = optimizeCompare(tree);
2362 /* if they are pointers they must be castable */
2363 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2364 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2365 werror(E_COMPARE_OP);
2366 fprintf(stderr,"comparing type ");
2367 printTypeChain(LTYPE(tree),stderr);
2368 fprintf(stderr,"to type ");
2369 printTypeChain(RTYPE(tree),stderr);
2370 fprintf(stderr,"\n");
2371 goto errorTreeReturn ;
2374 /* else they should be promotable to one another */
2376 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2377 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2379 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2380 werror(E_COMPARE_OP);
2381 fprintf(stderr,"comparing type ");
2382 printTypeChain(LTYPE(tree),stderr);
2383 fprintf(stderr,"to type ");
2384 printTypeChain(RTYPE(tree),stderr);
2385 fprintf(stderr,"\n");
2386 goto errorTreeReturn ;
2390 /* if they are both literal then */
2391 /* rewrite the tree */
2392 if (IS_LITERAL(RTYPE(tree)) &&
2393 IS_LITERAL(LTYPE(tree))) {
2394 tree->type = EX_VALUE ;
2395 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2396 valFromType(RETYPE(tree)),
2398 tree->right = tree->left = NULL;
2399 TETYPE(tree) = getSpec(TTYPE(tree) =
2400 tree->opval.val->type);
2403 LRVAL(tree) = RRVAL(tree) = 1;
2404 TTYPE(tree) = TETYPE(tree) = newCharLink();
2407 /*------------------------------------------------------------------*/
2408 /*----------------------------*/
2410 /*----------------------------*/
2411 case SIZEOF : /* evaluate wihout code generation */
2412 /* change the type to a integer */
2413 tree->type = EX_VALUE;
2414 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2415 tree->opval.val = constVal(buffer);
2416 tree->right = tree->left = NULL;
2417 TETYPE(tree) = getSpec(TTYPE(tree) =
2418 tree->opval.val->type);
2421 /*------------------------------------------------------------------*/
2422 /*----------------------------*/
2423 /* conditional operator '?' */
2424 /*----------------------------*/
2426 /* the type is one on the left */
2427 TTYPE(tree) = LTYPE(tree);
2428 TETYPE(tree)= getSpec (TTYPE(tree));
2432 /* if they don't match we have a problem */
2433 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2434 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2435 goto errorTreeReturn ;
2438 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2439 TETYPE(tree)= getSpec(TTYPE(tree));
2443 /*------------------------------------------------------------------*/
2444 /*----------------------------*/
2445 /* assignment operators */
2446 /*----------------------------*/
2449 /* for these it must be both must be integral */
2450 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2451 !IS_ARITHMETIC(RTYPE(tree))) {
2452 werror (E_OPS_INTEGRAL);
2453 goto errorTreeReturn ;
2456 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2458 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2459 werror(E_CODE_WRITE," ");
2462 werror(E_LVALUE_REQUIRED,"*= or /=");
2463 goto errorTreeReturn ;
2473 /* for these it must be both must be integral */
2474 if (!IS_INTEGRAL(LTYPE(tree)) ||
2475 !IS_INTEGRAL(RTYPE(tree))) {
2476 werror (E_OPS_INTEGRAL);
2477 goto errorTreeReturn ;
2480 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2482 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2483 werror(E_CODE_WRITE," ");
2486 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2487 goto errorTreeReturn ;
2492 /*------------------------------------------------------------------*/
2493 /*----------------------------*/
2495 /*----------------------------*/
2497 if (!(IS_PTR(LTYPE(tree)) ||
2498 IS_ARITHMETIC(LTYPE(tree)))) {
2499 werror(E_PLUS_INVALID,"-=");
2500 goto errorTreeReturn ;
2503 if (!(IS_PTR(RTYPE(tree)) ||
2504 IS_ARITHMETIC(RTYPE(tree)))) {
2505 werror(E_PLUS_INVALID,"-=");
2506 goto errorTreeReturn ;
2509 TETYPE(tree) = getSpec (TTYPE(tree) =
2510 computeType(LTYPE(tree),
2513 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2514 werror(E_CODE_WRITE," ");
2517 werror(E_LVALUE_REQUIRED,"-=");
2518 goto errorTreeReturn ;
2523 /*------------------------------------------------------------------*/
2524 /*----------------------------*/
2526 /*----------------------------*/
2528 /* this is not a unary operation */
2529 /* if both pointers then problem */
2530 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2531 werror(E_PTR_PLUS_PTR);
2532 goto errorTreeReturn ;
2535 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2536 werror(E_PLUS_INVALID,"+=");
2537 goto errorTreeReturn ;
2540 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2541 werror(E_PLUS_INVALID,"+=");
2542 goto errorTreeReturn;
2545 TETYPE(tree) = getSpec (TTYPE(tree) =
2546 computeType(LTYPE(tree),
2549 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2550 werror(E_CODE_WRITE," ");
2553 werror(E_LVALUE_REQUIRED,"+=");
2554 goto errorTreeReturn ;
2557 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2558 tree->opval.op = '=';
2561 /*------------------------------------------------------------------*/
2562 /*----------------------------*/
2563 /* straight assignemnt */
2564 /*----------------------------*/
2566 /* cannot be an aggregate */
2567 if (IS_AGGREGATE(LTYPE(tree))) {
2568 werror(E_AGGR_ASSIGN);
2569 goto errorTreeReturn;
2572 /* they should either match or be castable */
2573 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2574 werror(E_TYPE_MISMATCH,"assignment"," ");
2575 fprintf(stderr,"type --> '");
2576 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2577 fprintf(stderr,"assigned to type --> '");
2578 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2579 goto errorTreeReturn ;
2582 /* if the left side of the tree is of type void
2583 then report error */
2584 if (IS_VOID(LTYPE(tree))) {
2585 werror(E_CAST_ZERO);
2586 fprintf(stderr,"type --> '");
2587 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2588 fprintf(stderr,"assigned to type --> '");
2589 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2592 /* extra checks for pointer types */
2593 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2594 !IS_GENPTR(LTYPE(tree))) {
2595 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2596 werror(W_PTR_ASSIGN);
2599 TETYPE(tree) = getSpec(TTYPE(tree) =
2603 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2604 werror(E_CODE_WRITE," ");
2607 werror(E_LVALUE_REQUIRED,"=");
2608 goto errorTreeReturn ;
2613 /*------------------------------------------------------------------*/
2614 /*----------------------------*/
2615 /* comma operator */
2616 /*----------------------------*/
2618 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2621 /*------------------------------------------------------------------*/
2622 /*----------------------------*/
2624 /*----------------------------*/
2629 if (processParms (tree->left,
2631 tree->right,&parmNumber))
2632 goto errorTreeReturn ;
2634 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2635 tree->left->args = reverseVal(tree->left->args);
2636 reverseParms(tree->right);
2639 tree->args = tree->left->args ;
2640 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2643 /*------------------------------------------------------------------*/
2644 /*----------------------------*/
2645 /* return statement */
2646 /*----------------------------*/
2651 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2652 werror(E_RETURN_MISMATCH);
2653 goto errorTreeReturn ;
2656 if (IS_VOID(currFunc->type->next)
2658 !IS_VOID(RTYPE(tree))) {
2659 werror(E_FUNC_VOID);
2660 goto errorTreeReturn ;
2663 /* if there is going to be a casing required then add it */
2664 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) {
2666 decorateType(newNode(CAST,
2667 newAst_LINK(copyLinkChain(currFunc->type->next)),
2676 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2677 werror(E_VOID_FUNC,currFunc->name);
2678 goto errorTreeReturn ;
2681 TTYPE(tree) = TETYPE(tree) = NULL ;
2684 /*------------------------------------------------------------------*/
2685 /*----------------------------*/
2686 /* switch statement */
2687 /*----------------------------*/
2689 /* the switch value must be an integer */
2690 if (!IS_INTEGRAL(LTYPE(tree))) {
2691 werror (E_SWITCH_NON_INTEGER);
2692 goto errorTreeReturn ;
2695 TTYPE(tree) = TETYPE(tree) = NULL ;
2698 /*------------------------------------------------------------------*/
2699 /*----------------------------*/
2701 /*----------------------------*/
2703 tree->left = backPatchLabels(tree->left,
2706 TTYPE(tree) = TETYPE(tree) = NULL;
2709 /*------------------------------------------------------------------*/
2710 /*----------------------------*/
2712 /*----------------------------*/
2715 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2716 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2717 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2719 /* if the for loop is reversible then
2720 reverse it otherwise do what we normally
2726 if (isLoopReversible (tree,&sym,&init,&end))
2727 return reverseLoop (tree,sym,init,end);
2729 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2730 AST_FOR(tree,continueLabel) ,
2731 AST_FOR(tree,falseLabel) ,
2732 AST_FOR(tree,condLabel) ,
2733 AST_FOR(tree,initExpr) ,
2734 AST_FOR(tree,condExpr) ,
2735 AST_FOR(tree,loopExpr),
2739 TTYPE(tree) = TETYPE(tree) = NULL ;
2743 /* some error found this tree will be killed */
2745 TTYPE(tree) = TETYPE(tree) = newCharLink();
2746 tree->opval.op = NULLOP ;
2752 /*-----------------------------------------------------------------*/
2753 /* sizeofOp - processes size of operation */
2754 /*-----------------------------------------------------------------*/
2755 value *sizeofOp( sym_link *type)
2759 /* get the size and convert it to character */
2760 sprintf (buff,"%d", getSize(type));
2762 /* now convert into value */
2763 return constVal (buff);
2767 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2768 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2769 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2770 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2771 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2772 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2773 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2775 /*-----------------------------------------------------------------*/
2776 /* backPatchLabels - change and or not operators to flow control */
2777 /*-----------------------------------------------------------------*/
2778 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2784 if ( ! (IS_ANDORNOT(tree)))
2787 /* if this an and */
2789 static int localLbl = 0 ;
2790 symbol *localLabel ;
2792 sprintf (buffer,"_and_%d",localLbl++);
2793 localLabel = newSymbol(buffer,NestLevel);
2795 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2797 /* if left is already a IFX then just change the if true label in that */
2798 if (!IS_IFX(tree->left))
2799 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2801 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2802 /* right is a IFX then just join */
2803 if (IS_IFX(tree->right))
2804 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2806 tree->right = createLabel(localLabel,tree->right);
2807 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2809 return newNode(NULLOP,tree->left,tree->right);
2812 /* if this is an or operation */
2814 static int localLbl = 0 ;
2815 symbol *localLabel ;
2817 sprintf (buffer,"_or_%d",localLbl++);
2818 localLabel = newSymbol(buffer,NestLevel);
2820 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2822 /* if left is already a IFX then just change the if true label in that */
2823 if (!IS_IFX(tree->left))
2824 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2826 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2827 /* right is a IFX then just join */
2828 if (IS_IFX(tree->right))
2829 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2831 tree->right = createLabel(localLabel,tree->right);
2832 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2834 return newNode(NULLOP,tree->left,tree->right);
2839 int wasnot = IS_NOT(tree->left);
2840 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2842 /* if the left is already a IFX */
2843 if ( ! IS_IFX(tree->left) )
2844 tree->left = newNode (IFX,tree->left,NULL);
2847 tree->left->trueLabel = trueLabel ;
2848 tree->left->falseLabel= falseLabel ;
2850 tree->left->trueLabel = falseLabel ;
2851 tree->left->falseLabel= trueLabel ;
2857 tree->trueLabel = trueLabel ;
2858 tree->falseLabel= falseLabel;
2865 /*-----------------------------------------------------------------*/
2866 /* createBlock - create expression tree for block */
2867 /*-----------------------------------------------------------------*/
2868 ast *createBlock ( symbol *decl, ast *body )
2872 /* if the block has nothing */
2876 ex = newNode(BLOCK,NULL,body);
2877 ex->values.sym = decl ;
2879 ex->right = ex->right ;
2885 /*-----------------------------------------------------------------*/
2886 /* createLabel - creates the expression tree for labels */
2887 /*-----------------------------------------------------------------*/
2888 ast *createLabel ( symbol *label, ast *stmnt )
2891 char name[SDCC_NAME_MAX+1];
2894 /* must create fresh symbol if the symbol name */
2895 /* exists in the symbol table, since there can */
2896 /* be a variable with the same name as the labl */
2897 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
2898 (csym->level == label->level))
2899 label = newSymbol(label->name,label->level);
2901 /* change the name before putting it in add _*/
2902 sprintf (name,"%s",label->name);
2904 /* put the label in the LabelSymbol table */
2905 /* but first check if a label of the same */
2907 if ( (csym = findSym(LabelTab,NULL,name)))
2908 werror(E_DUPLICATE_LABEL,label->name);
2910 addSym (LabelTab, label, name,label->level,0);
2913 label->key = labelKey++ ;
2914 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
2920 /*-----------------------------------------------------------------*/
2921 /* createCase - generates the parsetree for a case statement */
2922 /*-----------------------------------------------------------------*/
2923 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
2925 char caseLbl[SDCC_NAME_MAX+1];
2929 /* if the switch statement does not exist */
2930 /* then case is out of context */
2932 werror(E_CASE_CONTEXT);
2936 caseVal = decorateType(resolveSymbols(caseVal));
2937 /* if not a constant then error */
2938 if (!IS_LITERAL(caseVal->ftype)) {
2939 werror(E_CASE_CONSTANT);
2943 /* if not a integer than error */
2944 if (!IS_INTEGRAL(caseVal->ftype)) {
2945 werror(E_CASE_NON_INTEGER);
2949 /* find the end of the switch values chain */
2950 if (!(val = swStat->values.switchVals.swVals))
2951 swStat->values.switchVals.swVals = caseVal->opval.val ;
2953 /* also order the cases according to value */
2955 int cVal = (int) floatFromVal(caseVal->opval.val);
2956 while (val && (int) floatFromVal(val) < cVal) {
2961 /* if we reached the end then */
2963 pval->next = caseVal->opval.val;
2965 /* we found a value greater than */
2966 /* the current value we must add this */
2967 /* before the value */
2968 caseVal->opval.val->next = val;
2970 /* if this was the first in chain */
2971 if (swStat->values.switchVals.swVals == val)
2972 swStat->values.switchVals.swVals =
2975 pval->next = caseVal->opval.val;
2980 /* create the case label */
2981 sprintf(caseLbl,"_case_%d_%d",
2982 swStat->values.switchVals.swNum,
2983 (int) floatFromVal(caseVal->opval.val));
2985 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
2990 /*-----------------------------------------------------------------*/
2991 /* createDefault - creates the parse tree for the default statement*/
2992 /*-----------------------------------------------------------------*/
2993 ast *createDefault (ast *swStat, ast *stmnt)
2995 char defLbl[SDCC_NAME_MAX+1];
2997 /* if the switch statement does not exist */
2998 /* then case is out of context */
3000 werror(E_CASE_CONTEXT);
3004 /* turn on the default flag */
3005 swStat->values.switchVals.swDefault = 1 ;
3007 /* create the label */
3008 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3009 return createLabel(newSymbol(defLbl,0),stmnt);
3012 /*-----------------------------------------------------------------*/
3013 /* createIf - creates the parsetree for the if statement */
3014 /*-----------------------------------------------------------------*/
3015 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3017 static int Lblnum = 0 ;
3019 symbol *ifTrue , *ifFalse, *ifEnd ;
3021 /* if neither exists */
3022 if (! elseBody && !ifBody)
3025 /* create the labels */
3026 sprintf (buffer,"_iffalse_%d",Lblnum);
3027 ifFalse = newSymbol (buffer,NestLevel);
3028 /* if no else body then end == false */
3032 sprintf (buffer,"_ifend_%d",Lblnum);
3033 ifEnd = newSymbol (buffer,NestLevel);
3036 sprintf (buffer,"_iftrue_%d",Lblnum);
3037 ifTrue = newSymbol (buffer,NestLevel);
3041 /* attach the ifTrue label to the top of it body */
3042 ifBody = createLabel(ifTrue,ifBody);
3043 /* attach a goto end to the ifBody if else is present */
3045 ifBody = newNode(NULLOP,ifBody,
3047 newAst_VALUE(symbolVal(ifEnd)),
3049 /* put the elseLabel on the else body */
3050 elseBody = createLabel (ifFalse,elseBody);
3051 /* out the end at the end of the body */
3052 elseBody = newNode(NULLOP,
3054 createLabel(ifEnd,NULL));
3057 ifBody = newNode(NULLOP,ifBody,
3058 createLabel(ifFalse,NULL));
3060 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3061 if (IS_IFX(condAst))
3064 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3066 return newNode(NULLOP,ifTree,
3067 newNode(NULLOP,ifBody,elseBody));
3071 /*-----------------------------------------------------------------*/
3072 /* createDo - creates parse tree for do */
3075 /* _docontinue_n: */
3076 /* condition_expression +-> trueLabel -> _dobody_n */
3078 /* +-> falseLabel-> _dobreak_n */
3080 /*-----------------------------------------------------------------*/
3081 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3082 symbol *falseLabel, ast *condAst, ast *doBody )
3087 /* if the body does not exist then it is simple */
3089 condAst = backPatchLabels(condAst,continueLabel,NULL);
3090 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3091 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3092 doTree->trueLabel = continueLabel ;
3093 doTree->falseLabel= NULL ;
3097 /* otherwise we have a body */
3098 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3100 /* attach the body label to the top */
3101 doBody = createLabel(trueLabel,doBody);
3102 /* attach the continue label to end of body */
3103 doBody = newNode(NULLOP, doBody,
3104 createLabel(continueLabel,NULL));
3106 /* now put the break label at the end */
3107 if (IS_IFX(condAst))
3110 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3112 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3114 /* putting it together */
3115 return newNode(NULLOP,doBody,doTree);
3118 /*-----------------------------------------------------------------*/
3119 /* createFor - creates parse tree for 'for' statement */
3122 /* condExpr +-> trueLabel -> _forbody_n */
3124 /* +-> falseLabel-> _forbreak_n */
3127 /* _forcontinue_n: */
3129 /* goto _forcond_n ; */
3131 /*-----------------------------------------------------------------*/
3132 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3133 symbol *falseLabel,symbol *condLabel ,
3134 ast *initExpr, ast *condExpr, ast *loopExpr,
3139 /* if loopexpression not present then we can generate it */
3140 /* the same way as a while */
3142 return newNode(NULLOP,initExpr,
3143 createWhile (trueLabel, continueLabel,
3144 falseLabel,condExpr, forBody ));
3145 /* vanilla for statement */
3146 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3148 if (condExpr && !IS_IFX(condExpr))
3149 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3152 /* attach condition label to condition */
3153 condExpr = createLabel(condLabel,condExpr);
3155 /* attach body label to body */
3156 forBody = createLabel(trueLabel,forBody);
3158 /* attach continue to forLoop expression & attach */
3159 /* goto the forcond @ and of loopExpression */
3160 loopExpr = createLabel(continueLabel,
3164 newAst_VALUE(symbolVal(condLabel)),
3166 /* now start putting them together */
3167 forTree = newNode(NULLOP,initExpr,condExpr);
3168 forTree = newNode(NULLOP,forTree,forBody);
3169 forTree = newNode(NULLOP,forTree,loopExpr);
3170 /* finally add the break label */
3171 forTree = newNode(NULLOP,forTree,
3172 createLabel(falseLabel,NULL));
3176 /*-----------------------------------------------------------------*/
3177 /* createWhile - creates parse tree for while statement */
3178 /* the while statement will be created as follows */
3180 /* _while_continue_n: */
3181 /* condition_expression +-> trueLabel -> _while_boby_n */
3183 /* +-> falseLabel -> _while_break_n*/
3184 /* _while_body_n: */
3186 /* goto _while_continue_n */
3187 /* _while_break_n: */
3188 /*-----------------------------------------------------------------*/
3189 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3190 symbol *falseLabel,ast *condExpr, ast *whileBody )
3194 /* put the continue label */
3195 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3196 condExpr = createLabel(continueLabel,condExpr);
3197 condExpr->lineno = 0;
3199 /* put the body label in front of the body */
3200 whileBody = createLabel(trueLabel,whileBody);
3201 whileBody->lineno = 0;
3202 /* put a jump to continue at the end of the body */
3203 /* and put break label at the end of the body */
3204 whileBody = newNode(NULLOP,
3207 newAst_VALUE(symbolVal(continueLabel)),
3208 createLabel(falseLabel,NULL)));
3210 /* put it all together */
3211 if ( IS_IFX(condExpr) )
3212 whileTree = condExpr ;
3214 whileTree = newNode (IFX, condExpr,NULL );
3215 /* put the true & false labels in place */
3216 whileTree->trueLabel = trueLabel ;
3217 whileTree->falseLabel= falseLabel;
3220 return newNode(NULLOP,whileTree,whileBody );
3223 /*-----------------------------------------------------------------*/
3224 /* optimizeGetHbit - get highest order bit of the expression */
3225 /*-----------------------------------------------------------------*/
3226 ast *optimizeGetHbit (ast *tree)
3229 /* if this is not a bit and */
3230 if (!IS_BITAND(tree))
3233 /* will look for tree of the form
3234 ( expr >> ((sizeof expr) -1) ) & 1 */
3235 if (!IS_AST_LIT_VALUE(tree->right))
3238 if (AST_LIT_VALUE(tree->right) != 1)
3241 if (!IS_RIGHT_OP(tree->left))
3244 if (!IS_AST_LIT_VALUE(tree->left->right))
3247 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3248 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3251 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3255 /*-----------------------------------------------------------------*/
3256 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3257 /*-----------------------------------------------------------------*/
3258 ast *optimizeRRCRLC ( ast *root )
3260 /* will look for trees of the form
3261 (?expr << 1) | (?expr >> 7) or
3262 (?expr >> 7) | (?expr << 1) will make that
3263 into a RLC : operation ..
3265 (?expr >> 1) | (?expr << 7) or
3266 (?expr << 7) | (?expr >> 1) will make that
3267 into a RRC operation
3268 note : by 7 I mean (number of bits required to hold the
3270 /* if the root operations is not a | operation the not */
3271 if (!IS_BITOR(root))
3274 /* I have to think of a better way to match patterns this sucks */
3275 /* that aside let start looking for the first case : I use a the
3276 negative check a lot to improve the efficiency */
3277 /* (?expr << 1) | (?expr >> 7) */
3278 if (IS_LEFT_OP(root->left) &&
3279 IS_RIGHT_OP(root->right) ) {
3281 if (!SPEC_USIGN(TETYPE(root->left->left)))
3284 if (!IS_AST_LIT_VALUE(root->left->right) ||
3285 !IS_AST_LIT_VALUE(root->right->right))
3288 /* make sure it is the same expression */
3289 if (!isAstEqual(root->left->left,
3293 if (AST_LIT_VALUE(root->left->right) != 1 )
3296 if (AST_LIT_VALUE(root->right->right) !=
3297 (getSize(TTYPE(root->left->left))*8 - 1))
3300 /* whew got the first case : create the AST */
3301 return newNode(RLC,root->left->left,NULL);
3305 /* check for second case */
3306 /* (?expr >> 7) | (?expr << 1) */
3307 if (IS_LEFT_OP(root->right) &&
3308 IS_RIGHT_OP(root->left) ) {
3310 if (!SPEC_USIGN(TETYPE(root->left->left)))
3313 if (!IS_AST_LIT_VALUE(root->left->right) ||
3314 !IS_AST_LIT_VALUE(root->right->right))
3317 /* make sure it is the same symbol */
3318 if (!isAstEqual(root->left->left,
3322 if (AST_LIT_VALUE(root->right->right) != 1 )
3325 if (AST_LIT_VALUE(root->left->right) !=
3326 (getSize(TTYPE(root->left->left))*8 - 1))
3329 /* whew got the first case : create the AST */
3330 return newNode(RLC,root->left->left,NULL);
3335 /* third case for RRC */
3336 /* (?symbol >> 1) | (?symbol << 7) */
3337 if (IS_LEFT_OP(root->right) &&
3338 IS_RIGHT_OP(root->left) ) {
3340 if (!SPEC_USIGN(TETYPE(root->left->left)))
3343 if (!IS_AST_LIT_VALUE(root->left->right) ||
3344 !IS_AST_LIT_VALUE(root->right->right))
3347 /* make sure it is the same symbol */
3348 if (!isAstEqual(root->left->left,
3352 if (AST_LIT_VALUE(root->left->right) != 1 )
3355 if (AST_LIT_VALUE(root->right->right) !=
3356 (getSize(TTYPE(root->left->left))*8 - 1))
3359 /* whew got the first case : create the AST */
3360 return newNode(RRC,root->left->left,NULL);
3364 /* fourth and last case for now */
3365 /* (?symbol << 7) | (?symbol >> 1) */
3366 if (IS_RIGHT_OP(root->right) &&
3367 IS_LEFT_OP(root->left) ) {
3369 if (!SPEC_USIGN(TETYPE(root->left->left)))
3372 if (!IS_AST_LIT_VALUE(root->left->right) ||
3373 !IS_AST_LIT_VALUE(root->right->right))
3376 /* make sure it is the same symbol */
3377 if (!isAstEqual(root->left->left,
3381 if (AST_LIT_VALUE(root->right->right) != 1 )
3384 if (AST_LIT_VALUE(root->left->right) !=
3385 (getSize(TTYPE(root->left->left))*8 - 1))
3388 /* whew got the first case : create the AST */
3389 return newNode(RRC,root->left->left,NULL);
3393 /* not found return root */
3397 /*-----------------------------------------------------------------*/
3398 /* optimizeCompare - otimizes compares for bit variables */
3399 /*-----------------------------------------------------------------*/
3400 ast *optimizeCompare ( ast *root )
3402 ast *optExpr = NULL;
3405 unsigned int litValue ;
3407 /* if nothing then return nothing */
3411 /* if not a compare op then do leaves */
3412 if (!IS_COMPARE_OP(root)) {
3413 root->left = optimizeCompare (root->left);
3414 root->right= optimizeCompare (root->right);
3418 /* if left & right are the same then depending
3419 of the operation do */
3420 if (isAstEqual(root->left,root->right)) {
3421 switch (root->opval.op) {
3425 optExpr = newAst_VALUE(constVal("0"));
3430 optExpr = newAst_VALUE(constVal("1"));
3434 return decorateType(optExpr);
3437 vleft = (root->left->type == EX_VALUE ?
3438 root->left->opval.val : NULL );
3440 vright = (root->right->type == EX_VALUE ?
3441 root->right->opval.val : NULL);
3443 /* if left is a BITVAR in BITSPACE */
3444 /* and right is a LITERAL then opt-*/
3445 /* imize else do nothing */
3446 if (vleft && vright &&
3447 IS_BITVAR(vleft->etype) &&
3448 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3449 IS_LITERAL(vright->etype)) {
3451 /* if right side > 1 then comparison may never succeed */
3452 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3453 werror(W_BAD_COMPARE);
3458 switch (root->opval.op) {
3459 case '>' : /* bit value greater than 1 cannot be */
3460 werror(W_BAD_COMPARE);
3464 case '<' : /* bit value < 1 means 0 */
3466 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3469 case LE_OP : /* bit value <= 1 means no check */
3470 optExpr = newAst_VALUE(vright);
3473 case GE_OP : /* bit value >= 1 means only check for = */
3475 optExpr = newAst_VALUE(vleft);
3478 } else { /* literal is zero */
3479 switch (root->opval.op) {
3480 case '<' : /* bit value < 0 cannot be */
3481 werror(W_BAD_COMPARE);
3485 case '>' : /* bit value > 0 means 1 */
3487 optExpr = newAst_VALUE(vleft);
3490 case LE_OP : /* bit value <= 0 means no check */
3491 case GE_OP : /* bit value >= 0 means no check */
3492 werror(W_BAD_COMPARE);
3496 case EQ_OP : /* bit == 0 means ! of bit */
3497 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3501 return decorateType(resolveSymbols(optExpr));
3502 } /* end-of-if of BITVAR */
3507 /*-----------------------------------------------------------------*/
3508 /* addSymToBlock : adds the symbol to the first block we find */
3509 /*-----------------------------------------------------------------*/
3510 void addSymToBlock (symbol *sym, ast *tree)
3512 /* reached end of tree or a leaf */
3513 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3517 if (IS_AST_OP(tree) &&
3518 tree->opval.op == BLOCK ) {
3520 symbol *lsym = copySymbol(sym);
3522 lsym->next = AST_VALUES(tree,sym);
3523 AST_VALUES(tree,sym) = lsym ;
3527 addSymToBlock(sym,tree->left);
3528 addSymToBlock(sym,tree->right);
3531 /*-----------------------------------------------------------------*/
3532 /* processRegParms - do processing for register parameters */
3533 /*-----------------------------------------------------------------*/
3534 static void processRegParms (value *args, ast *body)
3537 if (IS_REGPARM(args->etype))
3538 addSymToBlock(args->sym,body);
3543 /*-----------------------------------------------------------------*/
3544 /* resetParmKey - resets the operandkeys for the symbols */
3545 /*-----------------------------------------------------------------*/
3546 DEFSETFUNC(resetParmKey)
3557 /*-----------------------------------------------------------------*/
3558 /* createFunction - This is the key node that calls the iCode for */
3559 /* generating the code for a function. Note code */
3560 /* is generated function by function, later when */
3561 /* add inter-procedural analysis this will change */
3562 /*-----------------------------------------------------------------*/
3563 ast *createFunction (symbol *name, ast *body )
3569 iCode *piCode = NULL;
3571 /* if check function return 0 then some problem */
3572 if (checkFunction (name) == 0)
3575 /* create a dummy block if none exists */
3577 body = newNode(BLOCK,NULL,NULL);
3581 /* check if the function name already in the symbol table */
3582 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3584 /* special case for compiler defined functions
3585 we need to add the name to the publics list : this
3586 actually means we are now compiling the compiler
3589 addSet(&publics,name);
3594 allocVariables(name);
3596 name->lastLine = yylineno;
3598 processFuncArgs(currFunc,0);
3600 /* set the stack pointer */
3601 /* PENDING: check this for the mcs51 */
3602 stackPtr = -port->stack.direction * port->stack.call_overhead;
3603 if (IS_ISR(name->etype))
3604 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3605 if (IS_RENT(name->etype) || options.stackAuto)
3606 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3608 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3610 fetype = getSpec(name->type); /* get the specifier for the function */
3611 /* if this is a reentrant function then */
3612 if (IS_RENT(fetype))
3615 allocParms (name->args); /* allocate the parameters */
3617 /* do processing for parameters that are passed in registers */
3618 processRegParms (name->args,body);
3620 /* set the stack pointer */
3624 /* allocate & autoinit the block variables */
3625 processBlockVars (body, &stack,ALLOCATE);
3627 /* save the stack information */
3628 if (options.useXstack)
3629 name->xstack = SPEC_STAK(fetype) = stack;
3631 name->stack = SPEC_STAK(fetype) = stack;
3633 /* name needs to be mangled */
3634 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3636 body = resolveSymbols(body); /* resolve the symbols */
3637 body = decorateType (body); /* propagateType & do semantic checks */
3639 ex = newAst_VALUE(symbolVal(name)); /* create name */
3640 ex = newNode (FUNCTION,ex,body);
3641 ex->values.args = name->args ;
3644 werror(E_FUNC_NO_CODE,name->name);
3648 /* create the node & generate intermediate code */
3649 codeOutFile = code->oFile;
3650 piCode = iCodeFromAst(ex);
3653 werror(E_FUNC_NO_CODE,name->name);
3657 eBBlockFromiCode(piCode);
3659 /* if there are any statics then do them */
3661 codeOutFile = statsg->oFile;
3662 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3668 /* dealloc the block variables */
3669 processBlockVars(body, &stack,DEALLOCATE);
3670 /* deallocate paramaters */
3671 deallocParms(name->args);
3673 if (IS_RENT(fetype))
3676 /* we are done freeup memory & cleanup */
3681 addSet(&operKeyReset,name);
3682 applyToSet(operKeyReset,resetParmKey);
3684 if (options.debug && !options.nodebug)
3685 cdbStructBlock(1,cdbFile);
3687 cleanUpLevel(LabelTab,0);
3688 cleanUpBlock(StructTab,1);
3689 cleanUpBlock(TypedefTab,1);
3691 xstack->syms = NULL;
3692 istack->syms = NULL;