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(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 this is a varagrs function... */
592 if (!defParm && actParm && func->hasVargs )
596 if (IS_CAST_OP(actParm)
597 || (IS_AST_LIT_VALUE(actParm) && actParm->values.literalFromCast))
599 /* Parameter was explicitly typecast; don't touch it. */
603 /* If it's a small integer, upcast to int. */
604 if (IS_INTEGRAL(actParm->ftype)
605 && getSize(actParm->ftype) < INTSIZE)
607 newType = newAst_LINK(INTTYPE);
610 if (IS_PTR(actParm->ftype) && !IS_GENPTR(actParm->ftype))
612 newType = newAst_LINK(copyLinkChain(actParm->ftype));
613 DCL_TYPE(newType->opval.lnk) = GPOINTER;
616 if (IS_AGGREGATE(actParm->ftype))
618 newType = newAst_LINK(copyLinkChain(actParm->ftype));
619 DCL_TYPE(newType->opval.lnk) = GPOINTER;
624 /* cast required; change this op to a cast. */
625 ast *parmCopy = resolveSymbols(copyAst(actParm));
627 actParm->type = EX_OP;
628 actParm->opval.op = CAST;
629 actParm->left = newType;
630 actParm->right= parmCopy;
631 decorateType(actParm);
636 /* if defined parameters ended but actual has not & */
638 if (! defParm && actParm &&
639 (options.stackAuto || IS_RENT(fetype)))
642 resolveSymbols(actParm);
643 /* if this is a PARAM node then match left & right */
644 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
646 return (processParms (func,defParm,actParm->left,parmNumber) ||
647 processParms (func,defParm->next, actParm->right,parmNumber) );
650 /* the parameter type must be atleast castable */
651 if (checkType(defParm->type,actParm->ftype) == 0) {
652 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
653 werror(E_CONTINUE,"defined type ");
654 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
655 werror(E_CONTINUE,"actual type ");
656 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
659 /* if the parameter is castable then add the cast */
660 if ( checkType (defParm->type,actParm->ftype) < 0) {
661 ast *pTree = resolveSymbols(copyAst(actParm));
663 /* now change the current one to a cast */
664 actParm->type = EX_OP ;
665 actParm->opval.op = CAST ;
666 actParm->left = newAst_LINK(defParm->type);
667 actParm->right= pTree ;
668 actParm->etype= defParm->etype;
669 actParm->ftype= defParm->type;
672 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
674 actParm->argSym = defParm->sym;
675 /* make a copy and change the regparm type to the defined parm */
676 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
677 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
681 /*-----------------------------------------------------------------*/
682 /* createIvalType - generates ival for basic types */
683 /*-----------------------------------------------------------------*/
684 ast *createIvalType ( ast *sym,sym_link *type, initList *ilist)
688 /* if initList is deep */
689 if ( ilist->type == INIT_DEEP )
690 ilist = ilist->init.deep ;
692 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
693 return decorateType(newNode('=',sym,iExpr));
696 /*-----------------------------------------------------------------*/
697 /* createIvalStruct - generates initial value for structures */
698 /*-----------------------------------------------------------------*/
699 ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
705 sflds = SPEC_STRUCT(type)->fields ;
706 if (ilist->type != INIT_DEEP) {
707 werror(E_INIT_STRUCT,"");
711 iloop = ilist->init.deep;
713 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
716 /* if we have come to end */
720 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
721 lAst = decorateType(resolveSymbols(lAst));
722 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
728 /*-----------------------------------------------------------------*/
729 /* createIvalArray - generates code for array initialization */
730 /*-----------------------------------------------------------------*/
731 ast *createIvalArray (ast *sym, sym_link *type, initList *ilist)
735 int lcnt = 0, size =0 ;
737 /* take care of the special case */
738 /* array of characters can be init */
740 if ( IS_CHAR(type->next) )
741 if ( (rast = createIvalCharPtr(sym,
743 decorateType(resolveSymbols(list2expr(ilist))))))
745 return decorateType(resolveSymbols(rast));
747 /* not the special case */
748 if (ilist->type != INIT_DEEP) {
749 werror(E_INIT_STRUCT,"");
753 iloop = ilist->init.deep ;
754 lcnt = DCL_ELEM(type);
760 aSym = newNode('[',sym,newAst_VALUE(valueFromLit(size-1)));
761 aSym = decorateType(resolveSymbols(aSym));
762 rast = createIval (aSym,type->next,iloop,rast) ;
763 iloop = (iloop ? iloop->next : NULL) ;
766 /* if not array limits given & we */
767 /* are out of initialisers then */
768 if (!DCL_ELEM(type) && !iloop)
771 /* no of elements given and we */
772 /* have generated for all of them */
777 /* if we have not been given a size */
779 DCL_ELEM(type) = size;
781 return decorateType(resolveSymbols(rast));
785 /*-----------------------------------------------------------------*/
786 /* createIvalCharPtr - generates initial values for char pointers */
787 /*-----------------------------------------------------------------*/
788 ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
792 /* if this is a pointer & right is a literal array then */
793 /* just assignment will do */
794 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
795 SPEC_SCLS(iexpr->etype) == S_CODE )
796 && IS_ARRAY(iexpr->ftype)))
797 return newNode('=',sym,iexpr);
799 /* left side is an array so we have to assign each */
801 if (( IS_LITERAL(iexpr->etype) ||
802 SPEC_SCLS(iexpr->etype) == S_CODE )
803 && IS_ARRAY(iexpr->ftype)) {
805 /* for each character generate an assignment */
806 /* to the array element */
807 char *s = SPEC_CVAL(iexpr->etype).v_char ;
811 rast = newNode(NULLOP,
815 newAst_VALUE(valueFromLit(i))),
816 newAst_VALUE(valueFromLit(*s))));
820 rast = newNode(NULLOP,
824 newAst_VALUE(valueFromLit(i))),
825 newAst_VALUE(valueFromLit(*s))));
826 return decorateType(resolveSymbols(rast));
832 /*-----------------------------------------------------------------*/
833 /* createIvalPtr - generates initial value for pointers */
834 /*-----------------------------------------------------------------*/
835 ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
841 if ( ilist->type == INIT_DEEP )
842 ilist = ilist->init.deep ;
844 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
846 /* if character pointer */
847 if (IS_CHAR(type->next))
848 if ((rast = createIvalCharPtr (sym,type,iexpr)))
851 return newNode('=',sym,iexpr);
854 /*-----------------------------------------------------------------*/
855 /* createIval - generates code for initial value */
856 /*-----------------------------------------------------------------*/
857 ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid)
864 /* if structure then */
866 rast = createIvalStruct(sym, type,ilist);
868 /* if this is a pointer */
870 rast = createIvalPtr(sym, type,ilist);
872 /* if this is an array */
874 rast = createIvalArray(sym, type,ilist);
876 /* if type is SPECIFIER */
878 rast = createIvalType (sym,type,ilist);
880 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
882 return decorateType(resolveSymbols(rast)) ;
885 /*-----------------------------------------------------------------*/
886 /* initAggregates - initialises aggregate variables with initv */
887 /*-----------------------------------------------------------------*/
888 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
890 return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
893 /*-----------------------------------------------------------------*/
894 /* gatherAutoInit - creates assignment expressions for initial */
896 /*-----------------------------------------------------------------*/
897 ast *gatherAutoInit ( symbol *autoChain )
904 for ( sym = autoChain ; sym ; sym = sym->next ) {
906 /* resolve the symbols in the ival */
908 resolveIvalSym(sym->ival);
910 /* if this is a static variable & has an */
911 /* initial value the code needs to be lifted */
912 /* here to the main portion since they can be */
913 /* initialised only once at the start */
914 if ( IS_STATIC(sym->etype) && sym->ival &&
915 SPEC_SCLS(sym->etype) != S_CODE) {
918 /* insert the symbol into the symbol table */
919 /* with level = 0 & name = rname */
920 newSym = copySymbol (sym);
921 addSym (SymbolTab,newSym,newSym->name,0,0);
923 /* now lift the code to main */
924 if (IS_AGGREGATE(sym->type))
925 work = initAggregates (sym, sym->ival,NULL);
927 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
928 list2expr(sym->ival));
930 setAstLineno(work,sym->lineDef);
934 staticAutos = newNode(NULLOP,staticAutos,work);
941 /* if there is an initial value */
942 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
943 if (IS_AGGREGATE(sym->type))
944 work = initAggregates (sym,sym->ival,NULL);
946 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
947 list2expr(sym->ival));
949 setAstLineno (work,sym->lineDef);
952 init = newNode(NULLOP,init,work);
961 /*-----------------------------------------------------------------*/
962 /* stringToSymbol - creates a symbol from a literal string */
963 /*-----------------------------------------------------------------*/
964 static value *stringToSymbol (value *val)
966 char name[SDCC_NAME_MAX+1];
967 static int charLbl = 0;
970 sprintf(name,"_str_%d",charLbl++);
971 sym = newSymbol(name,0); /* make it @ level 0 */
972 strcpy(sym->rname,name);
974 /* copy the type from the value passed */
975 sym->type = copyLinkChain(val->type);
976 sym->etype = getSpec(sym->type);
977 /* change to storage class & output class */
978 SPEC_SCLS(sym->etype) = S_CODE ;
979 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
980 SPEC_STAT(sym->etype) = 1;
981 /* make the level & block = 0 */
982 sym->block = sym->level = 0;
985 sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
992 return symbolVal(sym);
996 /*-----------------------------------------------------------------*/
997 /* processBlockVars - will go thru the ast looking for block if */
998 /* a block is found then will allocate the syms */
999 /* will also gather the auto inits present */
1000 /*-----------------------------------------------------------------*/
1001 ast *processBlockVars ( ast *tree , int *stack, int action)
1006 /* if this is a block */
1007 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
1010 if (action == ALLOCATE) {
1011 autoInit = gatherAutoInit (tree->values.sym);
1012 *stack += allocVariables (tree->values.sym);
1014 /* if there are auto inits then do them */
1016 tree->left = newNode(NULLOP,autoInit,tree->left);
1017 } else /* action is deallocate */
1018 deallocLocal (tree->values.sym) ;
1021 processBlockVars (tree->left, stack, action);
1022 processBlockVars (tree->right, stack, action);
1026 /*-----------------------------------------------------------------*/
1027 /* constExprValue - returns the value of a constant expression */
1028 /*-----------------------------------------------------------------*/
1029 value *constExprValue (ast *cexpr, int check)
1031 cexpr = decorateType(resolveSymbols(cexpr));
1033 /* if this is not a constant then */
1034 if (!IS_LITERAL(cexpr->ftype)) {
1035 /* then check if this is a literal array
1037 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
1038 SPEC_CVAL(cexpr->etype).v_char &&
1039 IS_ARRAY(cexpr->ftype)) {
1040 value *val = valFromType(cexpr->ftype);
1041 SPEC_SCLS(val->etype) = S_LITERAL;
1042 val->sym =cexpr->opval.val->sym ;
1043 val->sym->type = copyLinkChain(cexpr->ftype);
1044 val->sym->etype = getSpec(val->sym->type);
1045 strcpy(val->name,cexpr->opval.val->sym->rname);
1049 /* if we are casting a literal value then */
1050 if (IS_AST_OP(cexpr) &&
1051 cexpr->opval.op == CAST &&
1052 IS_LITERAL(cexpr->left->ftype))
1053 return valCastLiteral(cexpr->ftype,
1054 floatFromVal(cexpr->left->opval.val));
1056 if (IS_AST_VALUE(cexpr))
1057 return cexpr->opval.val;
1060 werror(E_CONST_EXPECTED,"found expression");
1065 /* return the value */
1066 return cexpr->opval.val ;
1070 /*-----------------------------------------------------------------*/
1071 /* isLabelInAst - will return true if a given label is found */
1072 /*-----------------------------------------------------------------*/
1073 bool isLabelInAst (symbol *label, ast *tree)
1075 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1078 if (IS_AST_OP(tree) &&
1079 tree->opval.op == LABEL &&
1080 isSymbolEqual(AST_SYMBOL(tree->left),label))
1083 return isLabelInAst(label,tree->right) &&
1084 isLabelInAst(label,tree->left);
1088 /*-----------------------------------------------------------------*/
1089 /* isLoopCountable - return true if the loop count can be determi- */
1090 /* -ned at compile time . */
1091 /*-----------------------------------------------------------------*/
1092 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1093 symbol **sym,ast **init, ast **end)
1096 /* the loop is considered countable if the following
1097 conditions are true :-
1099 a) initExpr :- <sym> = <const>
1100 b) condExpr :- <sym> < <const1>
1101 c) loopExpr :- <sym> ++
1104 /* first check the initExpr */
1105 if ( IS_AST_OP(initExpr) &&
1106 initExpr->opval.op == '=' && /* is assignment */
1107 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1109 *sym = AST_SYMBOL(initExpr->left);
1110 *init= initExpr->right;
1115 /* for now the symbol has to be of
1117 if (!IS_INTEGRAL((*sym)->type))
1120 /* now check condExpr */
1121 if (IS_AST_OP(condExpr)) {
1123 switch (condExpr->opval.op) {
1125 if (IS_AST_SYM_VALUE(condExpr->left) &&
1126 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1127 IS_AST_LIT_VALUE(condExpr->right)) {
1128 *end = condExpr->right;
1134 if (IS_AST_OP(condExpr->left) &&
1135 condExpr->left->opval.op == '>' &&
1136 IS_AST_LIT_VALUE(condExpr->left->right) &&
1137 IS_AST_SYM_VALUE(condExpr->left->left)&&
1138 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1140 *end = newNode('+', condExpr->left->right,
1141 newAst_VALUE(constVal("1")));
1152 /* check loop expression is of the form <sym>++ */
1153 if (!IS_AST_OP(loopExpr))
1156 /* check if <sym> ++ */
1157 if (loopExpr->opval.op == INC_OP) {
1159 if (loopExpr->left) {
1161 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1162 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1167 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1168 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1175 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1177 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1178 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1179 IS_AST_LIT_VALUE(loopExpr->right) &&
1180 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1188 /*-----------------------------------------------------------------*/
1189 /* astHasVolatile - returns true if ast contains any volatile */
1190 /*-----------------------------------------------------------------*/
1191 bool astHasVolatile (ast *tree)
1196 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1199 if (IS_AST_OP(tree))
1200 return astHasVolatile(tree->left) ||
1201 astHasVolatile(tree->right);
1206 /*-----------------------------------------------------------------*/
1207 /* astHasPointer - return true if the ast contains any ptr variable*/
1208 /*-----------------------------------------------------------------*/
1209 bool astHasPointer (ast *tree)
1214 if (IS_AST_LINK(tree))
1217 /* if we hit an array expression then check
1218 only the left side */
1219 if (IS_AST_OP(tree) && tree->opval.op == '[')
1220 return astHasPointer(tree->left);
1222 if (IS_AST_VALUE(tree))
1223 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1225 return astHasPointer(tree->left) ||
1226 astHasPointer(tree->right);
1230 /*-----------------------------------------------------------------*/
1231 /* astHasSymbol - return true if the ast has the given symbol */
1232 /*-----------------------------------------------------------------*/
1233 bool astHasSymbol (ast *tree, symbol *sym)
1235 if (!tree || IS_AST_LINK(tree))
1238 if (IS_AST_VALUE(tree)) {
1239 if (IS_AST_SYM_VALUE(tree))
1240 return isSymbolEqual(AST_SYMBOL(tree),sym);
1245 return astHasSymbol(tree->left,sym) ||
1246 astHasSymbol(tree->right,sym);
1249 /*-----------------------------------------------------------------*/
1250 /* isConformingBody - the loop body has to conform to a set of rules */
1251 /* for the loop to be considered reversible read on for rules */
1252 /*-----------------------------------------------------------------*/
1253 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1256 /* we are going to do a pre-order traversal of the
1257 tree && check for the following conditions. (essentially
1258 a set of very shallow tests )
1259 a) the sym passed does not participate in
1260 any arithmetic operation
1261 b) There are no function calls
1262 c) all jumps are within the body
1263 d) address of loop control variable not taken
1264 e) if an assignment has a pointer on the
1265 left hand side make sure right does not have
1266 loop control variable */
1268 /* if we reach the end or a leaf then true */
1269 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1273 /* if anything else is "volatile" */
1274 if (IS_VOLATILE(TETYPE(pbody)))
1277 /* we will walk the body in a pre-order traversal for
1279 switch (pbody->opval.op) {
1280 /*------------------------------------------------------------------*/
1282 return isConformingBody (pbody->right,sym,body);
1284 /*------------------------------------------------------------------*/
1289 /*------------------------------------------------------------------*/
1290 case INC_OP: /* incerement operator unary so left only */
1293 /* sure we are not sym is not modified */
1295 IS_AST_SYM_VALUE(pbody->left) &&
1296 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1300 IS_AST_SYM_VALUE(pbody->right) &&
1301 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1306 /*------------------------------------------------------------------*/
1308 case '*' : /* can be unary : if right is null then unary operation */
1313 /* if right is NULL then unary operation */
1314 /*------------------------------------------------------------------*/
1315 /*----------------------------*/
1317 /*----------------------------*/
1318 if ( ! pbody->right ) {
1319 if (IS_AST_SYM_VALUE(pbody->left) &&
1320 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1323 return isConformingBody(pbody->left,sym,body) ;
1325 if (astHasSymbol(pbody->left,sym) ||
1326 astHasSymbol(pbody->right,sym))
1331 /*------------------------------------------------------------------*/
1339 if (IS_AST_SYM_VALUE(pbody->left) &&
1340 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1343 if (IS_AST_SYM_VALUE(pbody->right) &&
1344 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1347 return isConformingBody(pbody->left,sym,body) &&
1348 isConformingBody(pbody->right,sym,body);
1355 if (IS_AST_SYM_VALUE(pbody->left) &&
1356 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1358 return isConformingBody (pbody->left,sym,body);
1360 /*------------------------------------------------------------------*/
1372 case SIZEOF: /* evaluate wihout code generation */
1374 return isConformingBody(pbody->left,sym,body) &&
1375 isConformingBody(pbody->right,sym,body);
1377 /*------------------------------------------------------------------*/
1380 /* if left has a pointer & right has loop
1381 control variable then we cannot */
1382 if (astHasPointer(pbody->left) &&
1383 astHasSymbol (pbody->right,sym))
1385 if (astHasVolatile(pbody->left))
1388 if (IS_AST_SYM_VALUE(pbody->left) &&
1389 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1392 if (astHasVolatile(pbody->left))
1395 return isConformingBody(pbody->left,sym,body) &&
1396 isConformingBody(pbody->right,sym,body);
1407 assert("Parser should not have generated this\n");
1409 /*------------------------------------------------------------------*/
1410 /*----------------------------*/
1411 /* comma operator */
1412 /*----------------------------*/
1414 return isConformingBody(pbody->left,sym,body) &&
1415 isConformingBody(pbody->right,sym,body);
1417 /*------------------------------------------------------------------*/
1418 /*----------------------------*/
1420 /*----------------------------*/
1424 /*------------------------------------------------------------------*/
1425 /*----------------------------*/
1426 /* return statement */
1427 /*----------------------------*/
1432 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1437 if (astHasSymbol(pbody->left,sym))
1444 return isConformingBody(pbody->left,sym,body) &&
1445 isConformingBody(pbody->right,sym,body);
1451 /*-----------------------------------------------------------------*/
1452 /* isLoopReversible - takes a for loop as input && returns true */
1453 /* if the for loop is reversible. If yes will set the value of */
1454 /* the loop control var & init value & termination value */
1455 /*-----------------------------------------------------------------*/
1456 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1457 ast **init, ast **end )
1459 /* if option says don't do it then don't */
1460 if (optimize.noLoopReverse)
1462 /* there are several tests to determine this */
1464 /* for loop has to be of the form
1465 for ( <sym> = <const1> ;
1466 [<sym> < <const2>] ;
1467 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1469 if (! isLoopCountable (AST_FOR(loop,initExpr),
1470 AST_FOR(loop,condExpr),
1471 AST_FOR(loop,loopExpr),
1472 loopCntrl,init,end))
1475 /* now do some serious checking on the body of the loop
1478 return isConformingBody(loop->left,*loopCntrl,loop->left);
1482 /*-----------------------------------------------------------------*/
1483 /* replLoopSym - replace the loop sym by loop sym -1 */
1484 /*-----------------------------------------------------------------*/
1485 static void replLoopSym ( ast *body, symbol *sym)
1488 if (!body || IS_AST_LINK(body))
1491 if (IS_AST_SYM_VALUE(body)) {
1493 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1496 body->opval.op = '-';
1497 body->left = newAst_VALUE(symbolVal(sym));
1498 body->right= newAst_VALUE(constVal("1"));
1506 replLoopSym(body->left,sym);
1507 replLoopSym(body->right,sym);
1511 /*-----------------------------------------------------------------*/
1512 /* reverseLoop - do the actual loop reversal */
1513 /*-----------------------------------------------------------------*/
1514 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1518 /* create the following tree
1523 if (sym) goto for_continue ;
1526 /* put it together piece by piece */
1527 rloop = newNode (NULLOP,
1528 createIf(newAst_VALUE(symbolVal(sym)),
1530 newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1533 newAst_VALUE(symbolVal(sym)),
1536 replLoopSym(loop->left, sym);
1538 rloop = newNode(NULLOP,
1540 newAst_VALUE(symbolVal(sym)),
1541 newNode('-',end,init)),
1542 createLabel(AST_FOR(loop,continueLabel),
1547 newAst_VALUE(symbolVal(sym)),
1548 newAst_VALUE(constVal("1"))),
1551 return decorateType(rloop);
1555 #define DEMAND_INTEGER_PROMOTION
1557 #ifdef DEMAND_INTEGER_PROMOTION
1559 /*-----------------------------------------------------------------*/
1560 /* walk a tree looking for the leaves. Add a typecast to the given */
1561 /* type to each value leaf node. */
1562 /*-----------------------------------------------------------------*/
1563 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1567 /* WTF? We should never get here. */
1571 if (!node->left && !node->right)
1573 /* We're at a leaf; if it's a value, apply the typecast */
1574 if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1576 *parentPtr = decorateType(newNode(CAST,
1577 newAst_LINK(copyLinkChain(type)),
1585 pushTypeCastToLeaves(type, node->left, &(node->left));
1589 pushTypeCastToLeaves(type, node->right, &(node->right));
1596 /*-----------------------------------------------------------------*/
1597 /* Given an assignment operation in a tree, determine if the LHS */
1598 /* (the result) has a different (integer) type than the RHS. */
1599 /* If so, walk the RHS and add a typecast to the type of the LHS */
1600 /* to all leaf nodes. */
1601 /*-----------------------------------------------------------------*/
1602 void propAsgType(ast *tree)
1604 #ifdef DEMAND_INTEGER_PROMOTION
1605 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1607 /* Nothing to do here... */
1611 if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
1613 pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1620 /*-----------------------------------------------------------------*/
1621 /* decorateType - compute type for this tree also does type cheking*/
1622 /* this is done bottom up, since type have to flow upwards*/
1623 /* it also does constant folding, and paramater checking */
1624 /*-----------------------------------------------------------------*/
1625 ast *decorateType (ast *tree)
1633 /* if already has type then do nothing */
1634 if ( tree->decorated )
1637 tree->decorated = 1;
1639 /* print the line */
1640 /* if not block & function */
1641 if ( tree->type == EX_OP &&
1642 ( tree->opval.op != FUNCTION &&
1643 tree->opval.op != BLOCK &&
1644 tree->opval.op != NULLOP )) {
1645 filename = tree->filename ;
1646 lineno = tree->lineno ;
1649 /* if any child is an error | this one is an error do nothing */
1650 if ( tree->isError ||
1651 ( tree->left && tree->left->isError) ||
1652 ( tree->right && tree->right->isError ))
1655 /*------------------------------------------------------------------*/
1656 /*----------------------------*/
1657 /* leaf has been reached */
1658 /*----------------------------*/
1659 /* if this is of type value */
1660 /* just get the type */
1661 if ( tree->type == EX_VALUE ) {
1663 if ( IS_LITERAL(tree->opval.val->etype) ) {
1665 /* if this is a character array then declare it */
1666 if (IS_ARRAY(tree->opval.val->type))
1667 tree->opval.val = stringToSymbol(tree->opval.val);
1669 /* otherwise just copy the type information */
1670 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1671 if (funcInChain(tree->opval.val->type)) {
1672 tree->hasVargs = tree->opval.val->sym->hasVargs;
1673 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1678 if ( tree->opval.val->sym ) {
1679 /* if the undefined flag is set then give error message */
1680 if (tree->opval.val->sym->undefined ) {
1681 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1683 TTYPE(tree) = TETYPE(tree) =
1684 tree->opval.val->type = tree->opval.val->sym->type =
1685 tree->opval.val->etype = tree->opval.val->sym->etype =
1686 copyLinkChain(INTTYPE);
1690 /* if impilicit i.e. struct/union member then no type */
1691 if (tree->opval.val->sym->implicit )
1692 TTYPE(tree) = TETYPE(tree) = NULL ;
1696 /* else copy the type */
1697 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1699 /* and mark it as referenced */
1700 tree->opval.val->sym->isref = 1;
1701 /* if this is of type function or function pointer */
1702 if (funcInChain(tree->opval.val->type)) {
1703 tree->hasVargs = tree->opval.val->sym->hasVargs;
1704 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1714 /* if type link for the case of cast */
1715 if ( tree->type == EX_LINK ) {
1716 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1723 dtl = decorateType (tree->left);
1724 dtr = decorateType (tree->right);
1726 /* this is to take care of situations
1727 when the tree gets rewritten */
1728 if (dtl != tree->left)
1730 if (dtr != tree->right)
1734 /* depending on type of operator do */
1736 switch (tree->opval.op) {
1737 /*------------------------------------------------------------------*/
1738 /*----------------------------*/
1740 /*----------------------------*/
1743 /* determine which is the array & which the index */
1744 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1746 ast *tempTree = tree->left ;
1747 tree->left = tree->right ;
1748 tree->right= tempTree ;
1751 /* first check if this is a array or a pointer */
1752 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1753 werror(E_NEED_ARRAY_PTR,"[]");
1754 goto errorTreeReturn ;
1757 /* check if the type of the idx */
1758 if (!IS_INTEGRAL(RTYPE(tree))) {
1759 werror(E_IDX_NOT_INT);
1760 goto errorTreeReturn ;
1763 /* if the left is an rvalue then error */
1765 werror(E_LVALUE_REQUIRED,"array access");
1766 goto errorTreeReturn ;
1769 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1772 /*------------------------------------------------------------------*/
1773 /*----------------------------*/
1775 /*----------------------------*/
1777 /* if this is not a structure */
1778 if (!IS_STRUCT(LTYPE(tree))) {
1779 werror(E_STRUCT_UNION,".");
1780 goto errorTreeReturn ;
1782 TTYPE(tree) = structElemType (LTYPE(tree),
1783 (tree->right->type == EX_VALUE ?
1784 tree->right->opval.val : NULL ),&tree->args);
1785 TETYPE(tree) = getSpec(TTYPE(tree));
1788 /*------------------------------------------------------------------*/
1789 /*----------------------------*/
1790 /* struct/union pointer */
1791 /*----------------------------*/
1793 /* if not pointer to a structure */
1794 if (!IS_PTR(LTYPE(tree))) {
1796 goto errorTreeReturn ;
1799 if (!IS_STRUCT(LTYPE(tree)->next)) {
1800 werror(E_STRUCT_UNION,"->");
1801 goto errorTreeReturn ;
1804 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1805 (tree->right->type == EX_VALUE ?
1806 tree->right->opval.val : NULL ),&tree->args);
1807 TETYPE(tree) = getSpec(TTYPE(tree));
1810 /*------------------------------------------------------------------*/
1811 /*----------------------------*/
1812 /* ++/-- operation */
1813 /*----------------------------*/
1814 case INC_OP: /* incerement operator unary so left only */
1817 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1818 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1819 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1820 werror(E_CODE_WRITE,"++/--");
1829 /*------------------------------------------------------------------*/
1830 /*----------------------------*/
1832 /*----------------------------*/
1833 case '&': /* can be unary */
1834 /* if right is NULL then unary operation */
1835 if ( tree->right ) /* not an unary operation */ {
1837 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1838 werror(E_BITWISE_OP);
1839 werror(E_CONTINUE,"left & right types are ");
1840 printTypeChain(LTYPE(tree),stderr);
1841 fprintf(stderr,",");
1842 printTypeChain(RTYPE(tree),stderr);
1843 fprintf(stderr,"\n");
1844 goto errorTreeReturn ;
1847 /* if they are both literal */
1848 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1849 tree->type = EX_VALUE ;
1850 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1851 valFromType(RETYPE(tree)),'&');
1853 tree->right = tree->left = NULL;
1854 TETYPE(tree) = tree->opval.val->etype ;
1855 TTYPE(tree) = tree->opval.val->type;
1859 /* see if this is a GETHBIT operation if yes
1862 ast *otree = optimizeGetHbit(tree);
1865 return decorateType(otree);
1868 /* if right or left is literal then result of that type*/
1869 if (IS_LITERAL(RTYPE(tree))) {
1871 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1872 TETYPE(tree) = getSpec(TTYPE(tree));
1873 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1876 if (IS_LITERAL(LTYPE(tree))) {
1877 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1878 TETYPE(tree) = getSpec(TTYPE(tree));
1879 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1884 computeType (LTYPE(tree), RTYPE(tree));
1885 TETYPE(tree) = getSpec(TTYPE(tree));
1888 LRVAL(tree) = RRVAL(tree) = 1;
1892 /*------------------------------------------------------------------*/
1893 /*----------------------------*/
1895 /*----------------------------*/
1897 p->class = DECLARATOR;
1898 /* if bit field then error */
1899 if (IS_BITVAR(tree->left->etype)) {
1900 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1901 goto errorTreeReturn ;
1904 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1905 werror (E_ILLEGAL_ADDR,"address of register variable");
1906 goto errorTreeReturn;
1909 if (IS_FUNC(LTYPE(tree))) {
1910 werror(E_ILLEGAL_ADDR,"address of function");
1911 goto errorTreeReturn ;
1915 werror(E_LVALUE_REQUIRED,"address of");
1916 goto errorTreeReturn ;
1918 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1919 DCL_TYPE(p) = CPOINTER ;
1920 DCL_PTR_CONST(p) = port->mem.code_ro;
1923 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1924 DCL_TYPE(p) = FPOINTER;
1926 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1927 DCL_TYPE(p) = PPOINTER ;
1929 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1930 DCL_TYPE(p) = IPOINTER ;
1932 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1933 DCL_TYPE(p) = EEPPOINTER ;
1935 DCL_TYPE(p) = POINTER ;
1937 if (IS_AST_SYM_VALUE(tree->left)) {
1938 AST_SYMBOL(tree->left)->addrtaken = 1;
1939 AST_SYMBOL(tree->left)->allocreq = 1;
1942 p->next = LTYPE(tree);
1944 TETYPE(tree) = getSpec(TTYPE(tree));
1945 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1946 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1951 /*------------------------------------------------------------------*/
1952 /*----------------------------*/
1954 /*----------------------------*/
1956 /* if the rewrite succeeds then don't go any furthur */
1958 ast *wtree = optimizeRRCRLC ( tree );
1960 return decorateType(wtree) ;
1962 /*------------------------------------------------------------------*/
1963 /*----------------------------*/
1965 /*----------------------------*/
1967 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1968 werror(E_BITWISE_OP);
1969 werror(E_CONTINUE,"left & right types are ");
1970 printTypeChain(LTYPE(tree),stderr);
1971 fprintf(stderr,",");
1972 printTypeChain(RTYPE(tree),stderr);
1973 fprintf(stderr,"\n");
1974 goto errorTreeReturn ;
1977 /* if they are both literal then */
1978 /* rewrite the tree */
1979 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1980 tree->type = EX_VALUE ;
1981 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1982 valFromType(RETYPE(tree)),
1984 tree->right = tree->left = NULL;
1985 TETYPE(tree) = tree->opval.val->etype;
1986 TTYPE(tree) = tree->opval.val->type;
1989 LRVAL(tree) = RRVAL(tree) = 1;
1990 TETYPE(tree) = getSpec (TTYPE(tree) =
1991 computeType(LTYPE(tree),
1994 /*------------------------------------------------------------------*/
1995 /*----------------------------*/
1997 /*----------------------------*/
1999 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2000 werror(E_INVALID_OP,"divide");
2001 goto errorTreeReturn ;
2003 /* if they are both literal then */
2004 /* rewrite the tree */
2005 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2006 tree->type = EX_VALUE ;
2007 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
2008 valFromType(RETYPE(tree)));
2009 tree->right = tree->left = NULL;
2010 TETYPE(tree) = getSpec(TTYPE(tree) =
2011 tree->opval.val->type);
2014 LRVAL(tree) = RRVAL(tree) = 1;
2015 TETYPE(tree) = getSpec (TTYPE(tree) =
2016 computeType(LTYPE(tree),
2020 /*------------------------------------------------------------------*/
2021 /*----------------------------*/
2023 /*----------------------------*/
2025 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
2026 werror(E_BITWISE_OP);
2027 werror(E_CONTINUE,"left & right types are ");
2028 printTypeChain(LTYPE(tree),stderr);
2029 fprintf(stderr,",");
2030 printTypeChain(RTYPE(tree),stderr);
2031 fprintf(stderr,"\n");
2032 goto errorTreeReturn ;
2034 /* if they are both literal then */
2035 /* rewrite the tree */
2036 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2037 tree->type = EX_VALUE ;
2038 tree->opval.val = valMod (valFromType(LETYPE(tree)),
2039 valFromType(RETYPE(tree)));
2040 tree->right = tree->left = NULL;
2041 TETYPE(tree) = getSpec(TTYPE(tree) =
2042 tree->opval.val->type);
2045 LRVAL(tree) = RRVAL(tree) = 1;
2046 TETYPE(tree) = getSpec (TTYPE(tree) =
2047 computeType(LTYPE(tree),
2051 /*------------------------------------------------------------------*/
2052 /*----------------------------*/
2053 /* address dereference */
2054 /*----------------------------*/
2055 case '*': /* can be unary : if right is null then unary operation */
2056 if ( ! tree->right ) {
2057 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2059 goto errorTreeReturn ;
2063 werror(E_LVALUE_REQUIRED,"pointer deref");
2064 goto errorTreeReturn ;
2066 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2067 LTYPE(tree)->next : NULL );
2068 TETYPE(tree) = getSpec(TTYPE(tree));
2069 tree->args = tree->left->args ;
2070 tree->hasVargs = tree->left->hasVargs ;
2071 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2075 /*------------------------------------------------------------------*/
2076 /*----------------------------*/
2077 /* multiplication */
2078 /*----------------------------*/
2079 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2080 werror(E_INVALID_OP,"multiplication");
2081 goto errorTreeReturn ;
2084 /* if they are both literal then */
2085 /* rewrite the tree */
2086 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2087 tree->type = EX_VALUE ;
2088 tree->opval.val = valMult (valFromType(LETYPE(tree)),
2089 valFromType(RETYPE(tree)));
2090 tree->right = tree->left = NULL;
2091 TETYPE(tree) = getSpec(TTYPE(tree) =
2092 tree->opval.val->type);
2096 /* if left is a literal exchange left & right */
2097 if (IS_LITERAL(LTYPE(tree))) {
2098 ast *tTree = tree->left ;
2099 tree->left = tree->right ;
2100 tree->right= tTree ;
2103 LRVAL(tree) = RRVAL(tree) = 1;
2104 TETYPE(tree) = getSpec (TTYPE(tree) =
2105 computeType(LTYPE(tree),
2109 /*------------------------------------------------------------------*/
2110 /*----------------------------*/
2111 /* unary '+' operator */
2112 /*----------------------------*/
2115 if ( ! tree->right ) {
2116 if (!IS_INTEGRAL(LTYPE(tree))) {
2117 werror(E_UNARY_OP,'+');
2118 goto errorTreeReturn ;
2121 /* if left is a literal then do it */
2122 if (IS_LITERAL(LTYPE(tree))) {
2123 tree->type = EX_VALUE ;
2124 tree->opval.val = valFromType(LETYPE(tree));
2126 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2130 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2134 /*------------------------------------------------------------------*/
2135 /*----------------------------*/
2137 /*----------------------------*/
2139 /* this is not a unary operation */
2140 /* if both pointers then problem */
2141 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2142 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2143 werror(E_PTR_PLUS_PTR);
2144 goto errorTreeReturn ;
2147 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2148 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2149 werror(E_PLUS_INVALID,"+");
2150 goto errorTreeReturn ;
2153 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2154 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2155 werror(E_PLUS_INVALID,"+");
2156 goto errorTreeReturn;
2158 /* if they are both literal then */
2159 /* rewrite the tree */
2160 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2161 tree->type = EX_VALUE ;
2162 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2163 valFromType(RETYPE(tree)));
2164 tree->right = tree->left = NULL;
2165 TETYPE(tree) = getSpec(TTYPE(tree) =
2166 tree->opval.val->type);
2170 /* if the right is a pointer or left is a literal
2171 xchange left & right */
2172 if (IS_ARRAY(RTYPE(tree)) ||
2173 IS_PTR(RTYPE(tree)) ||
2174 IS_LITERAL(LTYPE(tree))) {
2175 ast *tTree = tree->left ;
2176 tree->left = tree->right ;
2177 tree->right= tTree ;
2180 LRVAL(tree) = RRVAL(tree) = 1;
2181 /* if the left is a pointer */
2182 if (IS_PTR(LTYPE(tree)))
2183 TETYPE(tree) = getSpec(TTYPE(tree) =
2186 TETYPE(tree) = getSpec(TTYPE(tree) =
2187 computeType(LTYPE(tree),
2191 /*------------------------------------------------------------------*/
2192 /*----------------------------*/
2194 /*----------------------------*/
2195 case '-' : /* can be unary */
2196 /* if right is null then unary */
2197 if ( ! tree->right ) {
2199 if (!IS_ARITHMETIC(LTYPE(tree))) {
2200 werror(E_UNARY_OP,tree->opval.op);
2201 goto errorTreeReturn ;
2204 /* if left is a literal then do it */
2205 if (IS_LITERAL(LTYPE(tree))) {
2206 tree->type = EX_VALUE ;
2207 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2209 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2213 TTYPE(tree) = LTYPE(tree);
2217 /*------------------------------------------------------------------*/
2218 /*----------------------------*/
2220 /*----------------------------*/
2222 if (!(IS_PTR(LTYPE(tree)) ||
2223 IS_ARRAY(LTYPE(tree)) ||
2224 IS_ARITHMETIC(LTYPE(tree)))) {
2225 werror(E_PLUS_INVALID,"-");
2226 goto errorTreeReturn ;
2229 if (!(IS_PTR(RTYPE(tree)) ||
2230 IS_ARRAY(RTYPE(tree)) ||
2231 IS_ARITHMETIC(RTYPE(tree)))) {
2232 werror(E_PLUS_INVALID,"-");
2233 goto errorTreeReturn ;
2236 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2237 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2238 IS_INTEGRAL(RTYPE(tree))) ) {
2239 werror(E_PLUS_INVALID,"-");
2240 goto errorTreeReturn ;
2243 /* if they are both literal then */
2244 /* rewrite the tree */
2245 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2246 tree->type = EX_VALUE ;
2247 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2248 valFromType(RETYPE(tree)));
2249 tree->right = tree->left = NULL;
2250 TETYPE(tree) = getSpec(TTYPE(tree) =
2251 tree->opval.val->type);
2255 /* if the left & right are equal then zero */
2256 if (isAstEqual(tree->left,tree->right)) {
2257 tree->type = EX_VALUE;
2258 tree->left = tree->right = NULL;
2259 tree->opval.val = constVal("0");
2260 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2264 /* if both of them are pointers or arrays then */
2265 /* the result is going to be an integer */
2266 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2267 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2268 TETYPE(tree) = TTYPE(tree) = newIntLink();
2270 /* if only the left is a pointer */
2271 /* then result is a pointer */
2272 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2273 TETYPE(tree) = getSpec(TTYPE(tree) =
2276 TETYPE(tree) = getSpec (TTYPE(tree) =
2277 computeType(LTYPE(tree),
2279 LRVAL(tree) = RRVAL(tree) = 1;
2282 /*------------------------------------------------------------------*/
2283 /*----------------------------*/
2285 /*----------------------------*/
2287 /* can be only integral type */
2288 if (!IS_INTEGRAL(LTYPE(tree))) {
2289 werror(E_UNARY_OP,tree->opval.op);
2290 goto errorTreeReturn ;
2293 /* if left is a literal then do it */
2294 if (IS_LITERAL(LTYPE(tree))) {
2295 tree->type = EX_VALUE ;
2296 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2298 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2302 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2305 /*------------------------------------------------------------------*/
2306 /*----------------------------*/
2308 /*----------------------------*/
2310 /* can be pointer */
2311 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2312 !IS_PTR(LTYPE(tree)) &&
2313 !IS_ARRAY(LTYPE(tree))) {
2314 werror(E_UNARY_OP,tree->opval.op);
2315 goto errorTreeReturn ;
2318 /* if left is a literal then do it */
2319 if (IS_LITERAL(LTYPE(tree))) {
2320 tree->type = EX_VALUE ;
2321 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2323 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2327 TTYPE(tree) = TETYPE(tree) = newCharLink();
2330 /*------------------------------------------------------------------*/
2331 /*----------------------------*/
2333 /*----------------------------*/
2336 TTYPE(tree) = LTYPE(tree);
2337 TETYPE(tree) = LETYPE(tree);
2341 TTYPE(tree) = TETYPE(tree) = newCharLink();
2346 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2347 werror(E_SHIFT_OP_INVALID);
2348 werror(E_CONTINUE,"left & right types are ");
2349 printTypeChain(LTYPE(tree),stderr);
2350 fprintf(stderr,",");
2351 printTypeChain(RTYPE(tree),stderr);
2352 fprintf(stderr,"\n");
2353 goto errorTreeReturn ;
2356 /* if they are both literal then */
2357 /* rewrite the tree */
2358 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2359 tree->type = EX_VALUE ;
2360 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2361 valFromType(RETYPE(tree)),
2362 (tree->opval.op == LEFT_OP ? 1 : 0));
2363 tree->right = tree->left = NULL;
2364 TETYPE(tree) = getSpec(TTYPE(tree) =
2365 tree->opval.val->type);
2368 /* if only the right side is a literal & we are
2369 shifting more than size of the left operand then zero */
2370 if (IS_LITERAL(RTYPE(tree)) &&
2371 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2372 (getSize(LTYPE(tree))*8)) {
2373 werror(W_SHIFT_CHANGED,
2374 (tree->opval.op == LEFT_OP ? "left" : "right"));
2375 tree->type = EX_VALUE;
2376 tree->left = tree->right = NULL;
2377 tree->opval.val = constVal("0");
2378 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2381 LRVAL(tree) = RRVAL(tree) = 1;
2382 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2383 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2385 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2389 /*------------------------------------------------------------------*/
2390 /*----------------------------*/
2392 /*----------------------------*/
2393 case CAST: /* change the type */
2394 /* cannot cast to an aggregate type */
2395 if (IS_AGGREGATE(LTYPE(tree))) {
2396 werror(E_CAST_ILLEGAL);
2397 goto errorTreeReturn ;
2400 /* if the right is a literal replace the tree */
2401 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2402 tree->type = EX_VALUE ;
2404 valCastLiteral(LTYPE(tree),
2405 floatFromVal(valFromType(RETYPE(tree))));
2408 TTYPE(tree) = tree->opval.val->type;
2409 tree->values.literalFromCast = 1;
2412 TTYPE(tree) = LTYPE(tree);
2416 TETYPE(tree) = getSpec(TTYPE(tree));
2420 /*------------------------------------------------------------------*/
2421 /*----------------------------*/
2422 /* logical &&, || */
2423 /*----------------------------*/
2426 /* each must me arithmetic type or be a pointer */
2427 if (!IS_PTR(LTYPE(tree)) &&
2428 !IS_ARRAY(LTYPE(tree)) &&
2429 !IS_INTEGRAL(LTYPE(tree))) {
2430 werror(E_COMPARE_OP);
2431 goto errorTreeReturn ;
2434 if (!IS_PTR(RTYPE(tree)) &&
2435 !IS_ARRAY(RTYPE(tree)) &&
2436 !IS_INTEGRAL(RTYPE(tree))) {
2437 werror(E_COMPARE_OP);
2438 goto errorTreeReturn ;
2440 /* if they are both literal then */
2441 /* rewrite the tree */
2442 if (IS_LITERAL(RTYPE(tree)) &&
2443 IS_LITERAL(LTYPE(tree))) {
2444 tree->type = EX_VALUE ;
2445 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2446 valFromType(RETYPE(tree)),
2448 tree->right = tree->left = NULL;
2449 TETYPE(tree) = getSpec(TTYPE(tree) =
2450 tree->opval.val->type);
2453 LRVAL(tree) = RRVAL(tree) = 1;
2454 TTYPE(tree) = TETYPE(tree) = newCharLink();
2457 /*------------------------------------------------------------------*/
2458 /*----------------------------*/
2459 /* comparison operators */
2460 /*----------------------------*/
2468 ast *lt = optimizeCompare(tree);
2474 /* if they are pointers they must be castable */
2475 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2476 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2477 werror(E_COMPARE_OP);
2478 fprintf(stderr,"comparing type ");
2479 printTypeChain(LTYPE(tree),stderr);
2480 fprintf(stderr,"to type ");
2481 printTypeChain(RTYPE(tree),stderr);
2482 fprintf(stderr,"\n");
2483 goto errorTreeReturn ;
2486 /* else they should be promotable to one another */
2488 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2489 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2491 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2492 werror(E_COMPARE_OP);
2493 fprintf(stderr,"comparing type ");
2494 printTypeChain(LTYPE(tree),stderr);
2495 fprintf(stderr,"to type ");
2496 printTypeChain(RTYPE(tree),stderr);
2497 fprintf(stderr,"\n");
2498 goto errorTreeReturn ;
2502 /* if they are both literal then */
2503 /* rewrite the tree */
2504 if (IS_LITERAL(RTYPE(tree)) &&
2505 IS_LITERAL(LTYPE(tree))) {
2506 tree->type = EX_VALUE ;
2507 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2508 valFromType(RETYPE(tree)),
2510 tree->right = tree->left = NULL;
2511 TETYPE(tree) = getSpec(TTYPE(tree) =
2512 tree->opval.val->type);
2515 LRVAL(tree) = RRVAL(tree) = 1;
2516 TTYPE(tree) = TETYPE(tree) = newCharLink();
2519 /*------------------------------------------------------------------*/
2520 /*----------------------------*/
2522 /*----------------------------*/
2523 case SIZEOF : /* evaluate wihout code generation */
2524 /* change the type to a integer */
2525 tree->type = EX_VALUE;
2526 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2527 tree->opval.val = constVal(buffer);
2528 tree->right = tree->left = NULL;
2529 TETYPE(tree) = getSpec(TTYPE(tree) =
2530 tree->opval.val->type);
2533 /*------------------------------------------------------------------*/
2534 /*----------------------------*/
2535 /* conditional operator '?' */
2536 /*----------------------------*/
2538 /* the type is one on the left */
2539 TTYPE(tree) = LTYPE(tree);
2540 TETYPE(tree)= getSpec (TTYPE(tree));
2544 /* if they don't match we have a problem */
2545 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2546 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2547 goto errorTreeReturn ;
2550 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2551 TETYPE(tree)= getSpec(TTYPE(tree));
2555 /*------------------------------------------------------------------*/
2556 /*----------------------------*/
2557 /* assignment operators */
2558 /*----------------------------*/
2561 /* for these it must be both must be integral */
2562 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2563 !IS_ARITHMETIC(RTYPE(tree))) {
2564 werror (E_OPS_INTEGRAL);
2565 goto errorTreeReturn ;
2568 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2570 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2571 werror(E_CODE_WRITE," ");
2574 werror(E_LVALUE_REQUIRED,"*= or /=");
2575 goto errorTreeReturn ;
2588 /* for these it must be both must be integral */
2589 if (!IS_INTEGRAL(LTYPE(tree)) ||
2590 !IS_INTEGRAL(RTYPE(tree))) {
2591 werror (E_OPS_INTEGRAL);
2592 goto errorTreeReturn ;
2595 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2597 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2598 werror(E_CODE_WRITE," ");
2601 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2602 goto errorTreeReturn ;
2610 /*------------------------------------------------------------------*/
2611 /*----------------------------*/
2613 /*----------------------------*/
2615 if (!(IS_PTR(LTYPE(tree)) ||
2616 IS_ARITHMETIC(LTYPE(tree)))) {
2617 werror(E_PLUS_INVALID,"-=");
2618 goto errorTreeReturn ;
2621 if (!(IS_PTR(RTYPE(tree)) ||
2622 IS_ARITHMETIC(RTYPE(tree)))) {
2623 werror(E_PLUS_INVALID,"-=");
2624 goto errorTreeReturn ;
2627 TETYPE(tree) = getSpec (TTYPE(tree) =
2628 computeType(LTYPE(tree),
2631 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2632 werror(E_CODE_WRITE," ");
2635 werror(E_LVALUE_REQUIRED,"-=");
2636 goto errorTreeReturn ;
2644 /*------------------------------------------------------------------*/
2645 /*----------------------------*/
2647 /*----------------------------*/
2649 /* this is not a unary operation */
2650 /* if both pointers then problem */
2651 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2652 werror(E_PTR_PLUS_PTR);
2653 goto errorTreeReturn ;
2656 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2657 werror(E_PLUS_INVALID,"+=");
2658 goto errorTreeReturn ;
2661 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2662 werror(E_PLUS_INVALID,"+=");
2663 goto errorTreeReturn;
2666 TETYPE(tree) = getSpec (TTYPE(tree) =
2667 computeType(LTYPE(tree),
2670 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2671 werror(E_CODE_WRITE," ");
2674 werror(E_LVALUE_REQUIRED,"+=");
2675 goto errorTreeReturn ;
2678 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2679 tree->opval.op = '=';
2685 /*------------------------------------------------------------------*/
2686 /*----------------------------*/
2687 /* straight assignemnt */
2688 /*----------------------------*/
2690 /* cannot be an aggregate */
2691 if (IS_AGGREGATE(LTYPE(tree))) {
2692 werror(E_AGGR_ASSIGN);
2693 goto errorTreeReturn;
2696 /* they should either match or be castable */
2697 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2698 werror(E_TYPE_MISMATCH,"assignment"," ");
2699 fprintf(stderr,"type --> '");
2700 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2701 fprintf(stderr,"assigned to type --> '");
2702 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2703 goto errorTreeReturn ;
2706 /* if the left side of the tree is of type void
2707 then report error */
2708 if (IS_VOID(LTYPE(tree))) {
2709 werror(E_CAST_ZERO);
2710 fprintf(stderr,"type --> '");
2711 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2712 fprintf(stderr,"assigned to type --> '");
2713 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2716 /* extra checks for pointer types */
2717 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2718 !IS_GENPTR(LTYPE(tree))) {
2719 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2720 werror(W_PTR_ASSIGN);
2723 TETYPE(tree) = getSpec(TTYPE(tree) =
2727 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2728 werror(E_CODE_WRITE," ");
2731 werror(E_LVALUE_REQUIRED,"=");
2732 goto errorTreeReturn ;
2739 /*------------------------------------------------------------------*/
2740 /*----------------------------*/
2741 /* comma operator */
2742 /*----------------------------*/
2744 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2747 /*------------------------------------------------------------------*/
2748 /*----------------------------*/
2750 /*----------------------------*/
2755 if (processParms (tree->left,
2757 tree->right,&parmNumber))
2758 goto errorTreeReturn ;
2760 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2761 tree->left->args = reverseVal(tree->left->args);
2762 reverseParms(tree->right);
2765 tree->args = tree->left->args ;
2766 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2769 /*------------------------------------------------------------------*/
2770 /*----------------------------*/
2771 /* return statement */
2772 /*----------------------------*/
2777 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2778 werror(E_RETURN_MISMATCH);
2779 goto errorTreeReturn ;
2782 if (IS_VOID(currFunc->type->next)
2784 !IS_VOID(RTYPE(tree))) {
2785 werror(E_FUNC_VOID);
2786 goto errorTreeReturn ;
2789 /* if there is going to be a casing required then add it */
2790 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2792 #if 0 && defined DEMAND_INTEGER_PROMOTION
2793 if (IS_INTEGRAL(currFunc->type->next))
2795 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2801 decorateType(newNode(CAST,
2802 newAst_LINK(copyLinkChain(currFunc->type->next)),
2812 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2813 werror(E_VOID_FUNC,currFunc->name);
2814 goto errorTreeReturn ;
2817 TTYPE(tree) = TETYPE(tree) = NULL ;
2820 /*------------------------------------------------------------------*/
2821 /*----------------------------*/
2822 /* switch statement */
2823 /*----------------------------*/
2825 /* the switch value must be an integer */
2826 if (!IS_INTEGRAL(LTYPE(tree))) {
2827 werror (E_SWITCH_NON_INTEGER);
2828 goto errorTreeReturn ;
2831 TTYPE(tree) = TETYPE(tree) = NULL ;
2834 /*------------------------------------------------------------------*/
2835 /*----------------------------*/
2837 /*----------------------------*/
2839 tree->left = backPatchLabels(tree->left,
2842 TTYPE(tree) = TETYPE(tree) = NULL;
2845 /*------------------------------------------------------------------*/
2846 /*----------------------------*/
2848 /*----------------------------*/
2851 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2852 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2853 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2855 /* if the for loop is reversible then
2856 reverse it otherwise do what we normally
2862 if (isLoopReversible (tree,&sym,&init,&end))
2863 return reverseLoop (tree,sym,init,end);
2865 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2866 AST_FOR(tree,continueLabel) ,
2867 AST_FOR(tree,falseLabel) ,
2868 AST_FOR(tree,condLabel) ,
2869 AST_FOR(tree,initExpr) ,
2870 AST_FOR(tree,condExpr) ,
2871 AST_FOR(tree,loopExpr),
2875 TTYPE(tree) = TETYPE(tree) = NULL ;
2879 /* some error found this tree will be killed */
2881 TTYPE(tree) = TETYPE(tree) = newCharLink();
2882 tree->opval.op = NULLOP ;
2888 /*-----------------------------------------------------------------*/
2889 /* sizeofOp - processes size of operation */
2890 /*-----------------------------------------------------------------*/
2891 value *sizeofOp( sym_link *type)
2895 /* get the size and convert it to character */
2896 sprintf (buff,"%d", getSize(type));
2898 /* now convert into value */
2899 return constVal (buff);
2903 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2904 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2905 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2906 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2907 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2908 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2909 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2911 /*-----------------------------------------------------------------*/
2912 /* backPatchLabels - change and or not operators to flow control */
2913 /*-----------------------------------------------------------------*/
2914 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2920 if ( ! (IS_ANDORNOT(tree)))
2923 /* if this an and */
2925 static int localLbl = 0 ;
2926 symbol *localLabel ;
2928 sprintf (buffer,"_and_%d",localLbl++);
2929 localLabel = newSymbol(buffer,NestLevel);
2931 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2933 /* if left is already a IFX then just change the if true label in that */
2934 if (!IS_IFX(tree->left))
2935 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2937 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2938 /* right is a IFX then just join */
2939 if (IS_IFX(tree->right))
2940 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2942 tree->right = createLabel(localLabel,tree->right);
2943 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2945 return newNode(NULLOP,tree->left,tree->right);
2948 /* if this is an or operation */
2950 static int localLbl = 0 ;
2951 symbol *localLabel ;
2953 sprintf (buffer,"_or_%d",localLbl++);
2954 localLabel = newSymbol(buffer,NestLevel);
2956 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2958 /* if left is already a IFX then just change the if true label in that */
2959 if (!IS_IFX(tree->left))
2960 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2962 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2963 /* right is a IFX then just join */
2964 if (IS_IFX(tree->right))
2965 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2967 tree->right = createLabel(localLabel,tree->right);
2968 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2970 return newNode(NULLOP,tree->left,tree->right);
2975 int wasnot = IS_NOT(tree->left);
2976 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2978 /* if the left is already a IFX */
2979 if ( ! IS_IFX(tree->left) )
2980 tree->left = newNode (IFX,tree->left,NULL);
2983 tree->left->trueLabel = trueLabel ;
2984 tree->left->falseLabel= falseLabel ;
2986 tree->left->trueLabel = falseLabel ;
2987 tree->left->falseLabel= trueLabel ;
2993 tree->trueLabel = trueLabel ;
2994 tree->falseLabel= falseLabel;
3001 /*-----------------------------------------------------------------*/
3002 /* createBlock - create expression tree for block */
3003 /*-----------------------------------------------------------------*/
3004 ast *createBlock ( symbol *decl, ast *body )
3008 /* if the block has nothing */
3012 ex = newNode(BLOCK,NULL,body);
3013 ex->values.sym = decl ;
3015 ex->right = ex->right ;
3021 /*-----------------------------------------------------------------*/
3022 /* createLabel - creates the expression tree for labels */
3023 /*-----------------------------------------------------------------*/
3024 ast *createLabel ( symbol *label, ast *stmnt )
3027 char name[SDCC_NAME_MAX+1];
3030 /* must create fresh symbol if the symbol name */
3031 /* exists in the symbol table, since there can */
3032 /* be a variable with the same name as the labl */
3033 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
3034 (csym->level == label->level))
3035 label = newSymbol(label->name,label->level);
3037 /* change the name before putting it in add _*/
3038 sprintf (name,"%s",label->name);
3040 /* put the label in the LabelSymbol table */
3041 /* but first check if a label of the same */
3043 if ( (csym = findSym(LabelTab,NULL,name)))
3044 werror(E_DUPLICATE_LABEL,label->name);
3046 addSym (LabelTab, label, name,label->level,0);
3049 label->key = labelKey++ ;
3050 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3056 /*-----------------------------------------------------------------*/
3057 /* createCase - generates the parsetree for a case statement */
3058 /*-----------------------------------------------------------------*/
3059 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
3061 char caseLbl[SDCC_NAME_MAX+1];
3065 /* if the switch statement does not exist */
3066 /* then case is out of context */
3068 werror(E_CASE_CONTEXT);
3072 caseVal = decorateType(resolveSymbols(caseVal));
3073 /* if not a constant then error */
3074 if (!IS_LITERAL(caseVal->ftype)) {
3075 werror(E_CASE_CONSTANT);
3079 /* if not a integer than error */
3080 if (!IS_INTEGRAL(caseVal->ftype)) {
3081 werror(E_CASE_NON_INTEGER);
3085 /* find the end of the switch values chain */
3086 if (!(val = swStat->values.switchVals.swVals))
3087 swStat->values.switchVals.swVals = caseVal->opval.val ;
3089 /* also order the cases according to value */
3091 int cVal = (int) floatFromVal(caseVal->opval.val);
3092 while (val && (int) floatFromVal(val) < cVal) {
3097 /* if we reached the end then */
3099 pval->next = caseVal->opval.val;
3101 /* we found a value greater than */
3102 /* the current value we must add this */
3103 /* before the value */
3104 caseVal->opval.val->next = val;
3106 /* if this was the first in chain */
3107 if (swStat->values.switchVals.swVals == val)
3108 swStat->values.switchVals.swVals =
3111 pval->next = caseVal->opval.val;
3116 /* create the case label */
3117 sprintf(caseLbl,"_case_%d_%d",
3118 swStat->values.switchVals.swNum,
3119 (int) floatFromVal(caseVal->opval.val));
3121 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3126 /*-----------------------------------------------------------------*/
3127 /* createDefault - creates the parse tree for the default statement*/
3128 /*-----------------------------------------------------------------*/
3129 ast *createDefault (ast *swStat, ast *stmnt)
3131 char defLbl[SDCC_NAME_MAX+1];
3133 /* if the switch statement does not exist */
3134 /* then case is out of context */
3136 werror(E_CASE_CONTEXT);
3140 /* turn on the default flag */
3141 swStat->values.switchVals.swDefault = 1 ;
3143 /* create the label */
3144 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3145 return createLabel(newSymbol(defLbl,0),stmnt);
3148 /*-----------------------------------------------------------------*/
3149 /* createIf - creates the parsetree for the if statement */
3150 /*-----------------------------------------------------------------*/
3151 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3153 static int Lblnum = 0 ;
3155 symbol *ifTrue , *ifFalse, *ifEnd ;
3157 /* if neither exists */
3158 if (! elseBody && !ifBody)
3161 /* create the labels */
3162 sprintf (buffer,"_iffalse_%d",Lblnum);
3163 ifFalse = newSymbol (buffer,NestLevel);
3164 /* if no else body then end == false */
3168 sprintf (buffer,"_ifend_%d",Lblnum);
3169 ifEnd = newSymbol (buffer,NestLevel);
3172 sprintf (buffer,"_iftrue_%d",Lblnum);
3173 ifTrue = newSymbol (buffer,NestLevel);
3177 /* attach the ifTrue label to the top of it body */
3178 ifBody = createLabel(ifTrue,ifBody);
3179 /* attach a goto end to the ifBody if else is present */
3181 ifBody = newNode(NULLOP,ifBody,
3183 newAst_VALUE(symbolVal(ifEnd)),
3185 /* put the elseLabel on the else body */
3186 elseBody = createLabel (ifFalse,elseBody);
3187 /* out the end at the end of the body */
3188 elseBody = newNode(NULLOP,
3190 createLabel(ifEnd,NULL));
3193 ifBody = newNode(NULLOP,ifBody,
3194 createLabel(ifFalse,NULL));
3196 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3197 if (IS_IFX(condAst))
3200 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3202 return newNode(NULLOP,ifTree,
3203 newNode(NULLOP,ifBody,elseBody));
3207 /*-----------------------------------------------------------------*/
3208 /* createDo - creates parse tree for do */
3211 /* _docontinue_n: */
3212 /* condition_expression +-> trueLabel -> _dobody_n */
3214 /* +-> falseLabel-> _dobreak_n */
3216 /*-----------------------------------------------------------------*/
3217 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3218 symbol *falseLabel, ast *condAst, ast *doBody )
3223 /* if the body does not exist then it is simple */
3225 condAst = backPatchLabels(condAst,continueLabel,NULL);
3226 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3227 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3228 doTree->trueLabel = continueLabel ;
3229 doTree->falseLabel= NULL ;
3233 /* otherwise we have a body */
3234 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3236 /* attach the body label to the top */
3237 doBody = createLabel(trueLabel,doBody);
3238 /* attach the continue label to end of body */
3239 doBody = newNode(NULLOP, doBody,
3240 createLabel(continueLabel,NULL));
3242 /* now put the break label at the end */
3243 if (IS_IFX(condAst))
3246 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3248 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3250 /* putting it together */
3251 return newNode(NULLOP,doBody,doTree);
3254 /*-----------------------------------------------------------------*/
3255 /* createFor - creates parse tree for 'for' statement */
3258 /* condExpr +-> trueLabel -> _forbody_n */
3260 /* +-> falseLabel-> _forbreak_n */
3263 /* _forcontinue_n: */
3265 /* goto _forcond_n ; */
3267 /*-----------------------------------------------------------------*/
3268 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3269 symbol *falseLabel,symbol *condLabel ,
3270 ast *initExpr, ast *condExpr, ast *loopExpr,
3275 /* if loopexpression not present then we can generate it */
3276 /* the same way as a while */
3278 return newNode(NULLOP,initExpr,
3279 createWhile (trueLabel, continueLabel,
3280 falseLabel,condExpr, forBody ));
3281 /* vanilla for statement */
3282 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3284 if (condExpr && !IS_IFX(condExpr))
3285 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3288 /* attach condition label to condition */
3289 condExpr = createLabel(condLabel,condExpr);
3291 /* attach body label to body */
3292 forBody = createLabel(trueLabel,forBody);
3294 /* attach continue to forLoop expression & attach */
3295 /* goto the forcond @ and of loopExpression */
3296 loopExpr = createLabel(continueLabel,
3300 newAst_VALUE(symbolVal(condLabel)),
3302 /* now start putting them together */
3303 forTree = newNode(NULLOP,initExpr,condExpr);
3304 forTree = newNode(NULLOP,forTree,forBody);
3305 forTree = newNode(NULLOP,forTree,loopExpr);
3306 /* finally add the break label */
3307 forTree = newNode(NULLOP,forTree,
3308 createLabel(falseLabel,NULL));
3312 /*-----------------------------------------------------------------*/
3313 /* createWhile - creates parse tree for while statement */
3314 /* the while statement will be created as follows */
3316 /* _while_continue_n: */
3317 /* condition_expression +-> trueLabel -> _while_boby_n */
3319 /* +-> falseLabel -> _while_break_n*/
3320 /* _while_body_n: */
3322 /* goto _while_continue_n */
3323 /* _while_break_n: */
3324 /*-----------------------------------------------------------------*/
3325 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3326 symbol *falseLabel,ast *condExpr, ast *whileBody )
3330 /* put the continue label */
3331 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3332 condExpr = createLabel(continueLabel,condExpr);
3333 condExpr->lineno = 0;
3335 /* put the body label in front of the body */
3336 whileBody = createLabel(trueLabel,whileBody);
3337 whileBody->lineno = 0;
3338 /* put a jump to continue at the end of the body */
3339 /* and put break label at the end of the body */
3340 whileBody = newNode(NULLOP,
3343 newAst_VALUE(symbolVal(continueLabel)),
3344 createLabel(falseLabel,NULL)));
3346 /* put it all together */
3347 if ( IS_IFX(condExpr) )
3348 whileTree = condExpr ;
3350 whileTree = newNode (IFX, condExpr,NULL );
3351 /* put the true & false labels in place */
3352 whileTree->trueLabel = trueLabel ;
3353 whileTree->falseLabel= falseLabel;
3356 return newNode(NULLOP,whileTree,whileBody );
3359 /*-----------------------------------------------------------------*/
3360 /* optimizeGetHbit - get highest order bit of the expression */
3361 /*-----------------------------------------------------------------*/
3362 ast *optimizeGetHbit (ast *tree)
3365 /* if this is not a bit and */
3366 if (!IS_BITAND(tree))
3369 /* will look for tree of the form
3370 ( expr >> ((sizeof expr) -1) ) & 1 */
3371 if (!IS_AST_LIT_VALUE(tree->right))
3374 if (AST_LIT_VALUE(tree->right) != 1)
3377 if (!IS_RIGHT_OP(tree->left))
3380 if (!IS_AST_LIT_VALUE(tree->left->right))
3383 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3384 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3387 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3391 /*-----------------------------------------------------------------*/
3392 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3393 /*-----------------------------------------------------------------*/
3394 ast *optimizeRRCRLC ( ast *root )
3396 /* will look for trees of the form
3397 (?expr << 1) | (?expr >> 7) or
3398 (?expr >> 7) | (?expr << 1) will make that
3399 into a RLC : operation ..
3401 (?expr >> 1) | (?expr << 7) or
3402 (?expr << 7) | (?expr >> 1) will make that
3403 into a RRC operation
3404 note : by 7 I mean (number of bits required to hold the
3406 /* if the root operations is not a | operation the not */
3407 if (!IS_BITOR(root))
3410 /* I have to think of a better way to match patterns this sucks */
3411 /* that aside let start looking for the first case : I use a the
3412 negative check a lot to improve the efficiency */
3413 /* (?expr << 1) | (?expr >> 7) */
3414 if (IS_LEFT_OP(root->left) &&
3415 IS_RIGHT_OP(root->right) ) {
3417 if (!SPEC_USIGN(TETYPE(root->left->left)))
3420 if (!IS_AST_LIT_VALUE(root->left->right) ||
3421 !IS_AST_LIT_VALUE(root->right->right))
3424 /* make sure it is the same expression */
3425 if (!isAstEqual(root->left->left,
3429 if (AST_LIT_VALUE(root->left->right) != 1 )
3432 if (AST_LIT_VALUE(root->right->right) !=
3433 (getSize(TTYPE(root->left->left))*8 - 1))
3436 /* whew got the first case : create the AST */
3437 return newNode(RLC,root->left->left,NULL);
3441 /* check for second case */
3442 /* (?expr >> 7) | (?expr << 1) */
3443 if (IS_LEFT_OP(root->right) &&
3444 IS_RIGHT_OP(root->left) ) {
3446 if (!SPEC_USIGN(TETYPE(root->left->left)))
3449 if (!IS_AST_LIT_VALUE(root->left->right) ||
3450 !IS_AST_LIT_VALUE(root->right->right))
3453 /* make sure it is the same symbol */
3454 if (!isAstEqual(root->left->left,
3458 if (AST_LIT_VALUE(root->right->right) != 1 )
3461 if (AST_LIT_VALUE(root->left->right) !=
3462 (getSize(TTYPE(root->left->left))*8 - 1))
3465 /* whew got the first case : create the AST */
3466 return newNode(RLC,root->left->left,NULL);
3471 /* third case for RRC */
3472 /* (?symbol >> 1) | (?symbol << 7) */
3473 if (IS_LEFT_OP(root->right) &&
3474 IS_RIGHT_OP(root->left) ) {
3476 if (!SPEC_USIGN(TETYPE(root->left->left)))
3479 if (!IS_AST_LIT_VALUE(root->left->right) ||
3480 !IS_AST_LIT_VALUE(root->right->right))
3483 /* make sure it is the same symbol */
3484 if (!isAstEqual(root->left->left,
3488 if (AST_LIT_VALUE(root->left->right) != 1 )
3491 if (AST_LIT_VALUE(root->right->right) !=
3492 (getSize(TTYPE(root->left->left))*8 - 1))
3495 /* whew got the first case : create the AST */
3496 return newNode(RRC,root->left->left,NULL);
3500 /* fourth and last case for now */
3501 /* (?symbol << 7) | (?symbol >> 1) */
3502 if (IS_RIGHT_OP(root->right) &&
3503 IS_LEFT_OP(root->left) ) {
3505 if (!SPEC_USIGN(TETYPE(root->left->left)))
3508 if (!IS_AST_LIT_VALUE(root->left->right) ||
3509 !IS_AST_LIT_VALUE(root->right->right))
3512 /* make sure it is the same symbol */
3513 if (!isAstEqual(root->left->left,
3517 if (AST_LIT_VALUE(root->right->right) != 1 )
3520 if (AST_LIT_VALUE(root->left->right) !=
3521 (getSize(TTYPE(root->left->left))*8 - 1))
3524 /* whew got the first case : create the AST */
3525 return newNode(RRC,root->left->left,NULL);
3529 /* not found return root */
3533 /*-----------------------------------------------------------------*/
3534 /* optimizeCompare - otimizes compares for bit variables */
3535 /*-----------------------------------------------------------------*/
3536 ast *optimizeCompare ( ast *root )
3538 ast *optExpr = NULL;
3541 unsigned int litValue ;
3543 /* if nothing then return nothing */
3547 /* if not a compare op then do leaves */
3548 if (!IS_COMPARE_OP(root)) {
3549 root->left = optimizeCompare (root->left);
3550 root->right= optimizeCompare (root->right);
3554 /* if left & right are the same then depending
3555 of the operation do */
3556 if (isAstEqual(root->left,root->right)) {
3557 switch (root->opval.op) {
3561 optExpr = newAst_VALUE(constVal("0"));
3566 optExpr = newAst_VALUE(constVal("1"));
3570 return decorateType(optExpr);
3573 vleft = (root->left->type == EX_VALUE ?
3574 root->left->opval.val : NULL );
3576 vright = (root->right->type == EX_VALUE ?
3577 root->right->opval.val : NULL);
3579 /* if left is a BITVAR in BITSPACE */
3580 /* and right is a LITERAL then opt-*/
3581 /* imize else do nothing */
3582 if (vleft && vright &&
3583 IS_BITVAR(vleft->etype) &&
3584 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3585 IS_LITERAL(vright->etype)) {
3587 /* if right side > 1 then comparison may never succeed */
3588 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3589 werror(W_BAD_COMPARE);
3594 switch (root->opval.op) {
3595 case '>' : /* bit value greater than 1 cannot be */
3596 werror(W_BAD_COMPARE);
3600 case '<' : /* bit value < 1 means 0 */
3602 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3605 case LE_OP : /* bit value <= 1 means no check */
3606 optExpr = newAst_VALUE(vright);
3609 case GE_OP : /* bit value >= 1 means only check for = */
3611 optExpr = newAst_VALUE(vleft);
3614 } else { /* literal is zero */
3615 switch (root->opval.op) {
3616 case '<' : /* bit value < 0 cannot be */
3617 werror(W_BAD_COMPARE);
3621 case '>' : /* bit value > 0 means 1 */
3623 optExpr = newAst_VALUE(vleft);
3626 case LE_OP : /* bit value <= 0 means no check */
3627 case GE_OP : /* bit value >= 0 means no check */
3628 werror(W_BAD_COMPARE);
3632 case EQ_OP : /* bit == 0 means ! of bit */
3633 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3637 return decorateType(resolveSymbols(optExpr));
3638 } /* end-of-if of BITVAR */
3643 /*-----------------------------------------------------------------*/
3644 /* addSymToBlock : adds the symbol to the first block we find */
3645 /*-----------------------------------------------------------------*/
3646 void addSymToBlock (symbol *sym, ast *tree)
3648 /* reached end of tree or a leaf */
3649 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3653 if (IS_AST_OP(tree) &&
3654 tree->opval.op == BLOCK ) {
3656 symbol *lsym = copySymbol(sym);
3658 lsym->next = AST_VALUES(tree,sym);
3659 AST_VALUES(tree,sym) = lsym ;
3663 addSymToBlock(sym,tree->left);
3664 addSymToBlock(sym,tree->right);
3667 /*-----------------------------------------------------------------*/
3668 /* processRegParms - do processing for register parameters */
3669 /*-----------------------------------------------------------------*/
3670 static void processRegParms (value *args, ast *body)
3673 if (IS_REGPARM(args->etype))
3674 addSymToBlock(args->sym,body);
3679 /*-----------------------------------------------------------------*/
3680 /* resetParmKey - resets the operandkeys for the symbols */
3681 /*-----------------------------------------------------------------*/
3682 DEFSETFUNC(resetParmKey)
3693 /*-----------------------------------------------------------------*/
3694 /* createFunction - This is the key node that calls the iCode for */
3695 /* generating the code for a function. Note code */
3696 /* is generated function by function, later when */
3697 /* add inter-procedural analysis this will change */
3698 /*-----------------------------------------------------------------*/
3699 ast *createFunction (symbol *name, ast *body )
3705 iCode *piCode = NULL;
3707 /* if check function return 0 then some problem */
3708 if (checkFunction (name) == 0)
3711 /* create a dummy block if none exists */
3713 body = newNode(BLOCK,NULL,NULL);
3717 /* check if the function name already in the symbol table */
3718 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3720 /* special case for compiler defined functions
3721 we need to add the name to the publics list : this
3722 actually means we are now compiling the compiler
3725 addSet(&publics,name);
3730 allocVariables(name);
3732 name->lastLine = yylineno;
3734 processFuncArgs(currFunc,0);
3736 /* set the stack pointer */
3737 /* PENDING: check this for the mcs51 */
3738 stackPtr = -port->stack.direction * port->stack.call_overhead;
3739 if (IS_ISR(name->etype))
3740 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3741 if (IS_RENT(name->etype) || options.stackAuto)
3742 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3744 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3746 fetype = getSpec(name->type); /* get the specifier for the function */
3747 /* if this is a reentrant function then */
3748 if (IS_RENT(fetype))
3751 allocParms (name->args); /* allocate the parameters */
3753 /* do processing for parameters that are passed in registers */
3754 processRegParms (name->args,body);
3756 /* set the stack pointer */
3760 /* allocate & autoinit the block variables */
3761 processBlockVars (body, &stack,ALLOCATE);
3763 /* save the stack information */
3764 if (options.useXstack)
3765 name->xstack = SPEC_STAK(fetype) = stack;
3767 name->stack = SPEC_STAK(fetype) = stack;
3769 /* name needs to be mangled */
3770 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3772 body = resolveSymbols(body); /* resolve the symbols */
3773 body = decorateType (body); /* propagateType & do semantic checks */
3775 ex = newAst_VALUE(symbolVal(name)); /* create name */
3776 ex = newNode (FUNCTION,ex,body);
3777 ex->values.args = name->args ;
3780 werror(E_FUNC_NO_CODE,name->name);
3784 /* create the node & generate intermediate code */
3785 codeOutFile = code->oFile;
3786 piCode = iCodeFromAst(ex);
3789 werror(E_FUNC_NO_CODE,name->name);
3793 eBBlockFromiCode(piCode);
3795 /* if there are any statics then do them */
3797 codeOutFile = statsg->oFile;
3798 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3804 /* dealloc the block variables */
3805 processBlockVars(body, &stack,DEALLOCATE);
3806 /* deallocate paramaters */
3807 deallocParms(name->args);
3809 if (IS_RENT(fetype))
3812 /* we are done freeup memory & cleanup */
3817 addSet(&operKeyReset,name);
3818 applyToSet(operKeyReset,resetParmKey);
3820 if (options.debug && !options.nodebug)
3821 cdbStructBlock(1,cdbFile);
3823 cleanUpLevel(LabelTab,0);
3824 cleanUpBlock(StructTab,1);
3825 cleanUpBlock(TypedefTab,1);
3827 xstack->syms = NULL;
3828 istack->syms = NULL;