1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
52 ast *createIval (ast *, sym_link *, initList *, ast *);
53 ast *createIvalCharPtr (ast *, sym_link *, ast *);
54 ast *optimizeRRCRLC ( ast * );
55 ast *optimizeGetHbit(ast *);
56 ast *backPatchLabels (ast *,symbol *,symbol *);
60 printTypeChain(tree->ftype,stdout);
65 /*-----------------------------------------------------------------*/
66 /* newAst - creates a fresh node for an expression tree */
67 /*-----------------------------------------------------------------*/
69 ast *newAst (int type, void *op )
72 static int oldLineno = 0 ;
74 ALLOC(ex,sizeof(ast));
77 ex->lineno = (noLineno ? oldLineno : yylineno);
78 ex->filename = currFname ;
79 ex->level = NestLevel ;
80 ex->block = currBlockno ;
81 ex->initMode = inInitMode;
83 /* depending on the type */
86 ex->opval.val = (value *) op;
89 ex->opval.op = (long) op ;
92 ex->opval.lnk = (sym_link *) op;
95 ex->opval.stmnt= (unsigned) op;
102 static ast* newAst_(unsigned type)
105 static int oldLineno = 0 ;
107 ALLOC(ex,sizeof(ast));
110 ex->lineno = (noLineno ? oldLineno : yylineno);
111 ex->filename = currFname ;
112 ex->level = NestLevel ;
113 ex->block = currBlockno ;
114 ex->initMode = inInitMode;
118 ast* newAst_VALUE(value*val)
120 ast* ex = newAst_(EX_VALUE);
125 ast* newAst_OP(unsigned op)
127 ast*ex = newAst_(EX_OP);
132 ast* newAst_LINK(sym_link*val)
134 ast* ex = newAst_(EX_LINK);
139 ast* newAst_STMNT(unsigned val)
141 ast* ex = newAst_(EX_STMNT);
142 ex->opval.stmnt = val;
146 /*-----------------------------------------------------------------*/
147 /* newNode - creates a new node */
148 /*-----------------------------------------------------------------*/
149 ast *newNode ( long op, ast *left, ast *right )
160 /*-----------------------------------------------------------------*/
161 /* newIfxNode - creates a new Ifx Node */
162 /*-----------------------------------------------------------------*/
163 ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel)
167 /* if this is a literal then we already know the result */
168 if (condAst->etype && IS_LITERAL(condAst->etype)) {
170 /* then depending on the expression value */
171 if ( floatFromVal(condAst->opval.val) )
172 ifxNode = newNode(GOTO,
173 newAst_VALUE(symbolVal(trueLabel)),
176 ifxNode = newNode(GOTO,
177 newAst_VALUE(symbolVal(falseLabel)),
181 ifxNode = newNode(IFX,condAst,NULL);
182 ifxNode->trueLabel = trueLabel;
183 ifxNode->falseLabel= falseLabel;
189 /*-----------------------------------------------------------------*/
190 /* copyAstValues - copies value portion of ast if needed */
191 /*-----------------------------------------------------------------*/
192 void copyAstValues (ast *dest,ast *src)
194 switch (src->opval.op) {
196 dest->values.sym = copySymbolChain(src->values.sym);
200 dest->values.switchVals.swVals =
201 copyValue(src->values.switchVals.swVals);
202 dest->values.switchVals.swDefault =
203 src->values.switchVals.swDefault ;
204 dest->values.switchVals.swNum =
205 src->values.switchVals.swNum ;
209 ALLOC_ATOMIC(dest->values.inlineasm,strlen(src->values.inlineasm));
210 strcpy(dest->values.inlineasm,src->values.inlineasm);
213 AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel));
214 AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel));
215 AST_FOR(dest,falseLabel) = copySymbol(AST_FOR(src,falseLabel));
216 AST_FOR(dest,condLabel) = copySymbol(AST_FOR(src,condLabel));
217 AST_FOR(dest,initExpr) = copyAst (AST_FOR(src,initExpr)) ;
218 AST_FOR(dest,condExpr) = copyAst (AST_FOR(src,condExpr)) ;
219 AST_FOR(dest,loopExpr) = copyAst (AST_FOR(src,loopExpr)) ;
224 /*-----------------------------------------------------------------*/
225 /* copyAst - makes a copy of a given astession */
226 /*-----------------------------------------------------------------*/
227 ast *copyAst (ast *src)
231 if (!src) return NULL ;
233 ALLOC(dest,sizeof(ast));
235 dest->type = src->type ;
236 dest->lineno = src->lineno ;
237 dest->level = src->level ;
238 dest->funcName = src->funcName;
239 dest->argSym = src->argSym;
241 /* if this is a leaf */
243 if (src->type == EX_VALUE) {
244 dest->opval.val = copyValue(src->opval.val);
249 if (src->type == EX_LINK) {
250 dest->opval.lnk = copyLinkChain(src->opval.lnk);
254 dest->opval.op = src->opval.op ;
256 /* if this is a node that has special values */
257 copyAstValues (dest,src);
260 dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ;
262 dest->trueLabel = copySymbol (src->trueLabel);
263 dest->falseLabel= copySymbol (src->falseLabel);
264 dest->left = copyAst(src->left);
265 dest->right= copyAst(src->right);
271 /*-----------------------------------------------------------------*/
272 /* hasSEFcalls - returns TRUE if tree has a function call */
273 /*-----------------------------------------------------------------*/
274 bool hasSEFcalls ( ast *tree)
279 if (tree->type == EX_OP &&
280 ( tree->opval.op == CALL ||
281 tree->opval.op == PCALL ||
282 tree->opval.op == '=' ||
283 tree->opval.op == INC_OP ||
284 tree->opval.op == DEC_OP ))
287 return ( hasSEFcalls(tree->left) |
288 hasSEFcalls(tree->right));
291 /*-----------------------------------------------------------------*/
292 /* isAstEqual - compares two asts & returns 1 if they are equal */
293 /*-----------------------------------------------------------------*/
294 int isAstEqual (ast *t1, ast *t2)
303 if (t1->type != t2->type)
308 if (t1->opval.op != t2->opval.op)
310 return ( isAstEqual(t1->left,t2->left) &&
311 isAstEqual(t1->right,t2->right));
315 if (t1->opval.val->sym) {
316 if (!t2->opval.val->sym)
319 return isSymbolEqual(t1->opval.val->sym,
323 if (t2->opval.val->sym)
326 return (floatFromVal(t1->opval.val) ==
327 floatFromVal(t2->opval.val));
331 /* only compare these two types */
339 /*-----------------------------------------------------------------*/
340 /* resolveSymbols - resolve symbols from the symbol table */
341 /*-----------------------------------------------------------------*/
342 ast *resolveSymbols (ast *tree)
344 /* walk the entire tree and check for values */
345 /* with symbols if we find one then replace */
346 /* symbol with that from the symbol table */
352 /* if not block & function */
353 if ( tree->type == EX_OP &&
354 ( tree->opval.op != FUNCTION &&
355 tree->opval.op != BLOCK &&
356 tree->opval.op != NULLOP )) {
357 filename = tree->filename ;
358 lineno = tree->lineno ;
361 /* make sure we resolve the true & false labels for ifx */
362 if (tree->type == EX_OP && tree->opval.op == IFX ) {
365 if (tree->trueLabel) {
366 if (( csym = findSym(LabelTab,tree->trueLabel,
367 tree->trueLabel->name)))
368 tree->trueLabel = csym ;
370 werror(E_LABEL_UNDEF,tree->trueLabel->name);
373 if (tree->falseLabel) {
374 if (( csym = findSym(LabelTab,
376 tree->falseLabel->name)))
377 tree->falseLabel = csym ;
379 werror(E_LABEL_UNDEF,tree->falseLabel->name);
384 /* if this is a label resolve it from the labelTab*/
385 if (IS_AST_VALUE(tree) &&
386 tree->opval.val->sym &&
387 tree->opval.val->sym->islbl) {
389 symbol *csym = findSym (LabelTab, tree->opval.val->sym ,
390 tree->opval.val->sym->name);
393 werror (E_LABEL_UNDEF,tree->opval.val->sym->name);
395 tree->opval.val->sym = csym ;
397 goto resolveChildren ;
400 /* do only for leafs */
401 if (IS_AST_VALUE(tree) &&
402 tree->opval.val->sym &&
403 ! tree->opval.val->sym->implicit ) {
405 symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym);
407 /* if found in the symbol table & they r not the same */
408 if (csym && tree->opval.val->sym != csym ) {
409 tree->opval.val->sym = csym ;
410 tree->opval.val->type = csym->type;
411 tree->opval.val->etype = csym->etype;
414 /* if not found in the symbol table */
415 /* mark it as undefined assume it is*/
416 /* an integer in data space */
417 if (!csym && !tree->opval.val->sym->implicit) {
419 /* if this is a function name then */
420 /* mark it as returning an int */
421 if (tree->funcName) {
422 tree->opval.val->sym->type = newLink();
423 DCL_TYPE(tree->opval.val->sym->type) = FUNCTION;
424 tree->opval.val->sym->type->next =
425 tree->opval.val->sym->etype = newIntLink();
426 tree->opval.val->etype = tree->opval.val->etype;
427 tree->opval.val->type = tree->opval.val->sym->type;
428 werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name);
430 tree->opval.val->sym->undefined =1 ;
431 tree->opval.val->type =
432 tree->opval.val->etype = newIntLink();
433 tree->opval.val->sym->type =
434 tree->opval.val->sym->etype = newIntLink();
440 resolveSymbols (tree->left);
441 resolveSymbols (tree->right);
446 /*-----------------------------------------------------------------*/
447 /* setAstLineno - walks a ast tree & sets the line number */
448 /*-----------------------------------------------------------------*/
449 int setAstLineno ( ast *tree, int lineno)
454 tree->lineno = lineno ;
455 setAstLineno ( tree->left, lineno);
456 setAstLineno ( tree->right, lineno);
461 /* this functions seems to be superfluous?! kmh */
463 /*-----------------------------------------------------------------*/
464 /* resolveFromTable - will return the symbal table value */
465 /*-----------------------------------------------------------------*/
466 value *resolveFromTable (value *val)
473 csym = findSymWithLevel (SymbolTab,val->sym);
475 /* if found in the symbol table & they r not the same */
476 if (csym && val->sym != csym &&
477 csym->level == val->sym->level &&
482 val->type = csym->type;
483 val->etype = csym->etype;
490 /*-----------------------------------------------------------------*/
491 /* funcOfType :- function of type with name */
492 /*-----------------------------------------------------------------*/
493 symbol *funcOfType (char *name, sym_link *type, sym_link *argType,
494 int nArgs , int rent)
498 /* create the symbol */
499 sym = newSymbol (name,0);
501 /* if arguments required */
505 args = sym->args = newValue();
508 argStack += getSize(type);
509 args->type = copyLinkChain(argType);
510 args->etype = getSpec(args->type);
513 args = args->next = newValue();
517 /* setup return value */
518 sym->type = newLink();
519 DCL_TYPE(sym->type) = FUNCTION;
520 sym->type->next = copyLinkChain(type);
521 sym->etype = getSpec(sym->type);
522 SPEC_RENT(sym->etype) = rent;
527 sym->argStack = (rent ? argStack : 0);
528 allocVariables (sym);
533 /*-----------------------------------------------------------------*/
534 /* reverseParms - will reverse a parameter tree */
535 /*-----------------------------------------------------------------*/
536 void reverseParms (ast *ptree)
542 /* top down if we find a nonParm tree then quit */
543 if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
545 ptree->left = ptree->right;
546 ptree->right = ttree;
547 reverseParms(ptree->left);
548 reverseParms(ptree->right);
554 /*-----------------------------------------------------------------*/
555 /* processParms - makes sure the parameters are okay and do some */
556 /* processing with them */
557 /*-----------------------------------------------------------------*/
558 int processParms (ast *func, value *defParm,
562 sym_link *fetype = func->etype;
564 /* if none of them exist */
565 if ( !defParm && !actParm)
568 /* if the function is being called via a pointer & */
569 /* it has not been defined a reentrant then we cannot*/
570 /* have parameters */
571 if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
572 werror (E_NONRENT_ARGS);
576 /* if defined parameters ended but actual parameters */
577 /* exist and this is not defined as a variable arg */
578 /* also check if statckAuto option is specified */
579 if ((! defParm) && actParm && (!func->hasVargs ) &&
580 !options.stackAuto && !IS_RENT(fetype)) {
581 werror(E_TOO_MANY_PARMS);
585 /* if defined parameters present and actual paramters ended */
586 if ( defParm && ! actParm) {
587 werror(E_TO_FEW_PARMS);
591 /* If 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;
618 /* cast required; change this op to a cast. */
619 ast *parmCopy = resolveSymbols(copyAst(actParm));
621 actParm->type = EX_OP;
622 actParm->opval.op = CAST;
623 actParm->left = newType;
624 actParm->right= parmCopy;
625 decorateType(actParm);
631 /* if defined parameters ended but actual has not & */
633 if (! defParm && actParm &&
634 (options.stackAuto || IS_RENT(fetype)))
637 resolveSymbols(actParm);
638 /* if this is a PARAM node then match left & right */
639 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
641 return (processParms (func,defParm,actParm->left,parmNumber) ||
642 processParms (func,defParm->next, actParm->right,parmNumber) );
645 /* the parameter type must be atleast castable */
646 if (checkType(defParm->type,actParm->ftype) == 0) {
647 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
648 werror(E_CONTINUE,"defined type ");
649 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
650 werror(E_CONTINUE,"actual type ");
651 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
654 /* if the parameter is castable then add the cast */
655 if ( checkType (defParm->type,actParm->ftype) < 0) {
656 ast *pTree = resolveSymbols(copyAst(actParm));
658 /* now change the current one to a cast */
659 actParm->type = EX_OP ;
660 actParm->opval.op = CAST ;
661 actParm->left = newAst_LINK(defParm->type);
662 actParm->right= pTree ;
663 actParm->etype= defParm->etype;
664 actParm->ftype= defParm->type;
667 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
668 actParm->argSym = defParm->sym;
669 /* make a copy and change the regparm type to the defined parm */
670 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
671 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
675 /*-----------------------------------------------------------------*/
676 /* createIvalType - generates ival for basic types */
677 /*-----------------------------------------------------------------*/
678 ast *createIvalType ( ast *sym,sym_link *type, initList *ilist)
682 /* if initList is deep */
683 if ( ilist->type == INIT_DEEP )
684 ilist = ilist->init.deep ;
686 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
687 return decorateType(newNode('=',sym,iExpr));
690 /*-----------------------------------------------------------------*/
691 /* createIvalStruct - generates initial value for structures */
692 /*-----------------------------------------------------------------*/
693 ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
699 sflds = SPEC_STRUCT(type)->fields ;
700 if (ilist->type != INIT_DEEP) {
701 werror(E_INIT_STRUCT,"");
705 iloop = ilist->init.deep;
707 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
710 /* if we have come to end */
714 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
715 lAst = decorateType(resolveSymbols(lAst));
716 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
722 /*-----------------------------------------------------------------*/
723 /* createIvalArray - generates code for array initialization */
724 /*-----------------------------------------------------------------*/
725 ast *createIvalArray (ast *sym, sym_link *type, initList *ilist)
729 int lcnt = 0, size =0 ;
731 /* take care of the special case */
732 /* array of characters can be init */
734 if ( IS_CHAR(type->next) )
735 if ( (rast = createIvalCharPtr(sym,
737 decorateType(resolveSymbols(list2expr(ilist))))))
739 return decorateType(resolveSymbols(rast));
741 /* not the special case */
742 if (ilist->type != INIT_DEEP) {
743 werror(E_INIT_STRUCT,"");
747 iloop = ilist->init.deep ;
748 lcnt = DCL_ELEM(type);
754 aSym = newNode('[',sym,newAst_VALUE(valueFromLit(size-1)));
755 aSym = decorateType(resolveSymbols(aSym));
756 rast = createIval (aSym,type->next,iloop,rast) ;
757 iloop = (iloop ? iloop->next : NULL) ;
760 /* if not array limits given & we */
761 /* are out of initialisers then */
762 if (!DCL_ELEM(type) && !iloop)
765 /* no of elements given and we */
766 /* have generated for all of them */
771 /* if we have not been given a size */
773 DCL_ELEM(type) = size;
775 return decorateType(resolveSymbols(rast));
779 /*-----------------------------------------------------------------*/
780 /* createIvalCharPtr - generates initial values for char pointers */
781 /*-----------------------------------------------------------------*/
782 ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
786 /* if this is a pointer & right is a literal array then */
787 /* just assignment will do */
788 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
789 SPEC_SCLS(iexpr->etype) == S_CODE )
790 && IS_ARRAY(iexpr->ftype)))
791 return newNode('=',sym,iexpr);
793 /* left side is an array so we have to assign each */
795 if (( IS_LITERAL(iexpr->etype) ||
796 SPEC_SCLS(iexpr->etype) == S_CODE )
797 && IS_ARRAY(iexpr->ftype)) {
799 /* for each character generate an assignment */
800 /* to the array element */
801 char *s = SPEC_CVAL(iexpr->etype).v_char ;
805 rast = newNode(NULLOP,
809 newAst_VALUE(valueFromLit(i))),
810 newAst_VALUE(valueFromLit(*s))));
814 rast = newNode(NULLOP,
818 newAst_VALUE(valueFromLit(i))),
819 newAst_VALUE(valueFromLit(*s))));
820 return decorateType(resolveSymbols(rast));
826 /*-----------------------------------------------------------------*/
827 /* createIvalPtr - generates initial value for pointers */
828 /*-----------------------------------------------------------------*/
829 ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
835 if ( ilist->type == INIT_DEEP )
836 ilist = ilist->init.deep ;
838 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
840 /* if character pointer */
841 if (IS_CHAR(type->next))
842 if ((rast = createIvalCharPtr (sym,type,iexpr)))
845 return newNode('=',sym,iexpr);
848 /*-----------------------------------------------------------------*/
849 /* createIval - generates code for initial value */
850 /*-----------------------------------------------------------------*/
851 ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid)
858 /* if structure then */
860 rast = createIvalStruct(sym, type,ilist);
862 /* if this is a pointer */
864 rast = createIvalPtr(sym, type,ilist);
866 /* if this is an array */
868 rast = createIvalArray(sym, type,ilist);
870 /* if type is SPECIFIER */
872 rast = createIvalType (sym,type,ilist);
874 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
876 return decorateType(resolveSymbols(rast)) ;
879 /*-----------------------------------------------------------------*/
880 /* initAggregates - initialises aggregate variables with initv */
881 /*-----------------------------------------------------------------*/
882 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
884 return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
887 /*-----------------------------------------------------------------*/
888 /* gatherAutoInit - creates assignment expressions for initial */
890 /*-----------------------------------------------------------------*/
891 ast *gatherAutoInit ( symbol *autoChain )
898 for ( sym = autoChain ; sym ; sym = sym->next ) {
900 /* resolve the symbols in the ival */
902 resolveIvalSym(sym->ival);
904 /* if this is a static variable & has an */
905 /* initial value the code needs to be lifted */
906 /* here to the main portion since they can be */
907 /* initialised only once at the start */
908 if ( IS_STATIC(sym->etype) && sym->ival &&
909 SPEC_SCLS(sym->etype) != S_CODE) {
912 /* insert the symbol into the symbol table */
913 /* with level = 0 & name = rname */
914 newSym = copySymbol (sym);
915 addSym (SymbolTab,newSym,newSym->name,0,0);
917 /* now lift the code to main */
918 if (IS_AGGREGATE(sym->type))
919 work = initAggregates (sym, sym->ival,NULL);
921 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
922 list2expr(sym->ival));
924 setAstLineno(work,sym->lineDef);
928 staticAutos = newNode(NULLOP,staticAutos,work);
935 /* if there is an initial value */
936 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
937 if (IS_AGGREGATE(sym->type))
938 work = initAggregates (sym,sym->ival,NULL);
940 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
941 list2expr(sym->ival));
943 setAstLineno (work,sym->lineDef);
946 init = newNode(NULLOP,init,work);
955 /*-----------------------------------------------------------------*/
956 /* stringToSymbol - creates a symbol from a literal string */
957 /*-----------------------------------------------------------------*/
958 static value *stringToSymbol (value *val)
960 char name[SDCC_NAME_MAX+1];
961 static int charLbl = 0;
964 sprintf(name,"_str_%d",charLbl++);
965 sym = newSymbol(name,0); /* make it @ level 0 */
966 strcpy(sym->rname,name);
968 /* copy the type from the value passed */
969 sym->type = copyLinkChain(val->type);
970 sym->etype = getSpec(sym->type);
971 /* change to storage class & output class */
972 SPEC_SCLS(sym->etype) = S_CODE ;
973 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
974 SPEC_STAT(sym->etype) = 1;
975 /* make the level & block = 0 */
976 sym->block = sym->level = 0;
979 sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
986 return symbolVal(sym);
990 /*-----------------------------------------------------------------*/
991 /* processBlockVars - will go thru the ast looking for block if */
992 /* a block is found then will allocate the syms */
993 /* will also gather the auto inits present */
994 /*-----------------------------------------------------------------*/
995 ast *processBlockVars ( ast *tree , int *stack, int action)
1000 /* if this is a block */
1001 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
1004 if (action == ALLOCATE) {
1005 autoInit = gatherAutoInit (tree->values.sym);
1006 *stack += allocVariables (tree->values.sym);
1008 /* if there are auto inits then do them */
1010 tree->left = newNode(NULLOP,autoInit,tree->left);
1011 } else /* action is deallocate */
1012 deallocLocal (tree->values.sym) ;
1015 processBlockVars (tree->left, stack, action);
1016 processBlockVars (tree->right, stack, action);
1020 /*-----------------------------------------------------------------*/
1021 /* constExprValue - returns the value of a constant expression */
1022 /*-----------------------------------------------------------------*/
1023 value *constExprValue (ast *cexpr, int check)
1025 cexpr = decorateType(resolveSymbols(cexpr));
1027 /* if this is not a constant then */
1028 if (!IS_LITERAL(cexpr->ftype)) {
1029 /* then check if this is a literal array
1031 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
1032 SPEC_CVAL(cexpr->etype).v_char &&
1033 IS_ARRAY(cexpr->ftype)) {
1034 value *val = valFromType(cexpr->ftype);
1035 SPEC_SCLS(val->etype) = S_LITERAL;
1036 val->sym =cexpr->opval.val->sym ;
1037 val->sym->type = copyLinkChain(cexpr->ftype);
1038 val->sym->etype = getSpec(val->sym->type);
1039 strcpy(val->name,cexpr->opval.val->sym->rname);
1043 /* if we are casting a literal value then */
1044 if (IS_AST_OP(cexpr) &&
1045 cexpr->opval.op == CAST &&
1046 IS_LITERAL(cexpr->left->ftype))
1047 return valCastLiteral(cexpr->ftype,
1048 floatFromVal(cexpr->left->opval.val));
1050 if (IS_AST_VALUE(cexpr))
1051 return cexpr->opval.val;
1054 werror(E_CONST_EXPECTED,"found expression");
1059 /* return the value */
1060 return cexpr->opval.val ;
1064 /*-----------------------------------------------------------------*/
1065 /* isLabelInAst - will return true if a given label is found */
1066 /*-----------------------------------------------------------------*/
1067 bool isLabelInAst (symbol *label, ast *tree)
1069 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1072 if (IS_AST_OP(tree) &&
1073 tree->opval.op == LABEL &&
1074 isSymbolEqual(AST_SYMBOL(tree->left),label))
1077 return isLabelInAst(label,tree->right) &&
1078 isLabelInAst(label,tree->left);
1082 /*-----------------------------------------------------------------*/
1083 /* isLoopCountable - return true if the loop count can be determi- */
1084 /* -ned at compile time . */
1085 /*-----------------------------------------------------------------*/
1086 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1087 symbol **sym,ast **init, ast **end)
1090 /* the loop is considered countable if the following
1091 conditions are true :-
1093 a) initExpr :- <sym> = <const>
1094 b) condExpr :- <sym> < <const1>
1095 c) loopExpr :- <sym> ++
1098 /* first check the initExpr */
1099 if ( IS_AST_OP(initExpr) &&
1100 initExpr->opval.op == '=' && /* is assignment */
1101 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1103 *sym = AST_SYMBOL(initExpr->left);
1104 *init= initExpr->right;
1109 /* for now the symbol has to be of
1111 if (!IS_INTEGRAL((*sym)->type))
1114 /* now check condExpr */
1115 if (IS_AST_OP(condExpr)) {
1117 switch (condExpr->opval.op) {
1119 if (IS_AST_SYM_VALUE(condExpr->left) &&
1120 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1121 IS_AST_LIT_VALUE(condExpr->right)) {
1122 *end = condExpr->right;
1128 if (IS_AST_OP(condExpr->left) &&
1129 condExpr->left->opval.op == '>' &&
1130 IS_AST_LIT_VALUE(condExpr->left->right) &&
1131 IS_AST_SYM_VALUE(condExpr->left->left)&&
1132 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1134 *end = newNode('+', condExpr->left->right,
1135 newAst_VALUE(constVal("1")));
1146 /* check loop expression is of the form <sym>++ */
1147 if (!IS_AST_OP(loopExpr))
1150 /* check if <sym> ++ */
1151 if (loopExpr->opval.op == INC_OP) {
1153 if (loopExpr->left) {
1155 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1156 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1161 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1162 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1169 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1171 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1172 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1173 IS_AST_LIT_VALUE(loopExpr->right) &&
1174 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1182 /*-----------------------------------------------------------------*/
1183 /* astHasVolatile - returns true if ast contains any volatile */
1184 /*-----------------------------------------------------------------*/
1185 bool astHasVolatile (ast *tree)
1190 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1193 if (IS_AST_OP(tree))
1194 return astHasVolatile(tree->left) ||
1195 astHasVolatile(tree->right);
1200 /*-----------------------------------------------------------------*/
1201 /* astHasPointer - return true if the ast contains any ptr variable*/
1202 /*-----------------------------------------------------------------*/
1203 bool astHasPointer (ast *tree)
1208 if (IS_AST_LINK(tree))
1211 /* if we hit an array expression then check
1212 only the left side */
1213 if (IS_AST_OP(tree) && tree->opval.op == '[')
1214 return astHasPointer(tree->left);
1216 if (IS_AST_VALUE(tree))
1217 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1219 return astHasPointer(tree->left) ||
1220 astHasPointer(tree->right);
1224 /*-----------------------------------------------------------------*/
1225 /* astHasSymbol - return true if the ast has the given symbol */
1226 /*-----------------------------------------------------------------*/
1227 bool astHasSymbol (ast *tree, symbol *sym)
1229 if (!tree || IS_AST_LINK(tree))
1232 if (IS_AST_VALUE(tree)) {
1233 if (IS_AST_SYM_VALUE(tree))
1234 return isSymbolEqual(AST_SYMBOL(tree),sym);
1239 return astHasSymbol(tree->left,sym) ||
1240 astHasSymbol(tree->right,sym);
1243 /*-----------------------------------------------------------------*/
1244 /* isConformingBody - the loop body has to conform to a set of rules */
1245 /* for the loop to be considered reversible read on for rules */
1246 /*-----------------------------------------------------------------*/
1247 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1250 /* we are going to do a pre-order traversal of the
1251 tree && check for the following conditions. (essentially
1252 a set of very shallow tests )
1253 a) the sym passed does not participate in
1254 any arithmetic operation
1255 b) There are no function calls
1256 c) all jumps are within the body
1257 d) address of loop control variable not taken
1258 e) if an assignment has a pointer on the
1259 left hand side make sure right does not have
1260 loop control variable */
1262 /* if we reach the end or a leaf then true */
1263 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1267 /* if anything else is "volatile" */
1268 if (IS_VOLATILE(TETYPE(pbody)))
1271 /* we will walk the body in a pre-order traversal for
1273 switch (pbody->opval.op) {
1274 /*------------------------------------------------------------------*/
1276 return isConformingBody (pbody->right,sym,body);
1278 /*------------------------------------------------------------------*/
1283 /*------------------------------------------------------------------*/
1284 case INC_OP: /* incerement operator unary so left only */
1287 /* sure we are not sym is not modified */
1289 IS_AST_SYM_VALUE(pbody->left) &&
1290 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1294 IS_AST_SYM_VALUE(pbody->right) &&
1295 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1300 /*------------------------------------------------------------------*/
1302 case '*' : /* can be unary : if right is null then unary operation */
1307 /* if right is NULL then unary operation */
1308 /*------------------------------------------------------------------*/
1309 /*----------------------------*/
1311 /*----------------------------*/
1312 if ( ! pbody->right ) {
1313 if (IS_AST_SYM_VALUE(pbody->left) &&
1314 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1317 return isConformingBody(pbody->left,sym,body) ;
1319 if (astHasSymbol(pbody->left,sym) ||
1320 astHasSymbol(pbody->right,sym))
1325 /*------------------------------------------------------------------*/
1333 if (IS_AST_SYM_VALUE(pbody->left) &&
1334 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1337 if (IS_AST_SYM_VALUE(pbody->right) &&
1338 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1341 return isConformingBody(pbody->left,sym,body) &&
1342 isConformingBody(pbody->right,sym,body);
1349 if (IS_AST_SYM_VALUE(pbody->left) &&
1350 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1352 return isConformingBody (pbody->left,sym,body);
1354 /*------------------------------------------------------------------*/
1366 case SIZEOF: /* evaluate wihout code generation */
1368 return isConformingBody(pbody->left,sym,body) &&
1369 isConformingBody(pbody->right,sym,body);
1371 /*------------------------------------------------------------------*/
1374 /* if left has a pointer & right has loop
1375 control variable then we cannot */
1376 if (astHasPointer(pbody->left) &&
1377 astHasSymbol (pbody->right,sym))
1379 if (astHasVolatile(pbody->left))
1382 if (IS_AST_SYM_VALUE(pbody->left) &&
1383 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1386 if (astHasVolatile(pbody->left))
1389 return isConformingBody(pbody->left,sym,body) &&
1390 isConformingBody(pbody->right,sym,body);
1401 assert("Parser should not have generated this\n");
1403 /*------------------------------------------------------------------*/
1404 /*----------------------------*/
1405 /* comma operator */
1406 /*----------------------------*/
1408 return isConformingBody(pbody->left,sym,body) &&
1409 isConformingBody(pbody->right,sym,body);
1411 /*------------------------------------------------------------------*/
1412 /*----------------------------*/
1414 /*----------------------------*/
1418 /*------------------------------------------------------------------*/
1419 /*----------------------------*/
1420 /* return statement */
1421 /*----------------------------*/
1426 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1431 if (astHasSymbol(pbody->left,sym))
1438 return isConformingBody(pbody->left,sym,body) &&
1439 isConformingBody(pbody->right,sym,body);
1445 /*-----------------------------------------------------------------*/
1446 /* isLoopReversible - takes a for loop as input && returns true */
1447 /* if the for loop is reversible. If yes will set the value of */
1448 /* the loop control var & init value & termination value */
1449 /*-----------------------------------------------------------------*/
1450 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1451 ast **init, ast **end )
1453 /* if option says don't do it then don't */
1454 if (optimize.noLoopReverse)
1456 /* there are several tests to determine this */
1458 /* for loop has to be of the form
1459 for ( <sym> = <const1> ;
1460 [<sym> < <const2>] ;
1461 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1463 if (! isLoopCountable (AST_FOR(loop,initExpr),
1464 AST_FOR(loop,condExpr),
1465 AST_FOR(loop,loopExpr),
1466 loopCntrl,init,end))
1469 /* now do some serious checking on the body of the loop
1472 return isConformingBody(loop->left,*loopCntrl,loop->left);
1476 /*-----------------------------------------------------------------*/
1477 /* replLoopSym - replace the loop sym by loop sym -1 */
1478 /*-----------------------------------------------------------------*/
1479 static void replLoopSym ( ast *body, symbol *sym)
1482 if (!body || IS_AST_LINK(body))
1485 if (IS_AST_SYM_VALUE(body)) {
1487 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1490 body->opval.op = '-';
1491 body->left = newAst_VALUE(symbolVal(sym));
1492 body->right= newAst_VALUE(constVal("1"));
1500 replLoopSym(body->left,sym);
1501 replLoopSym(body->right,sym);
1505 /*-----------------------------------------------------------------*/
1506 /* reverseLoop - do the actual loop reversal */
1507 /*-----------------------------------------------------------------*/
1508 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1512 /* create the following tree
1517 if (sym) goto for_continue ;
1520 /* put it together piece by piece */
1521 rloop = newNode (NULLOP,
1522 createIf(newAst_VALUE(symbolVal(sym)),
1524 newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1527 newAst_VALUE(symbolVal(sym)),
1530 replLoopSym(loop->left, sym);
1532 rloop = newNode(NULLOP,
1534 newAst_VALUE(symbolVal(sym)),
1535 newNode('-',end,init)),
1536 createLabel(AST_FOR(loop,continueLabel),
1541 newAst_VALUE(symbolVal(sym)),
1542 newAst_VALUE(constVal("1"))),
1545 return decorateType(rloop);
1549 #define DEMAND_INTEGER_PROMOTION
1551 #ifdef DEMAND_INTEGER_PROMOTION
1553 /*-----------------------------------------------------------------*/
1554 /* walk a tree looking for the leaves. Add a typecast to the given */
1555 /* type to each value leaf node. */
1556 /*-----------------------------------------------------------------*/
1557 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1561 /* WTF? We should never get here. */
1565 if (!node->left && !node->right)
1567 /* We're at a leaf; if it's a value, apply the typecast */
1568 if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1570 *parentPtr = decorateType(newNode(CAST,
1571 newAst_LINK(copyLinkChain(type)),
1579 pushTypeCastToLeaves(type, node->left, &(node->left));
1583 pushTypeCastToLeaves(type, node->right, &(node->right));
1590 /*-----------------------------------------------------------------*/
1591 /* Given an assignment operation in a tree, determine if the LHS */
1592 /* (the result) has a different (integer) type than the RHS. */
1593 /* If so, walk the RHS and add a typecast to the type of the LHS */
1594 /* to all leaf nodes. */
1595 /*-----------------------------------------------------------------*/
1596 void propAsgType(ast *tree)
1598 #ifdef DEMAND_INTEGER_PROMOTION
1599 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1601 /* Nothing to do here... */
1605 if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
1607 pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1614 /*-----------------------------------------------------------------*/
1615 /* decorateType - compute type for this tree also does type cheking*/
1616 /* this is done bottom up, since type have to flow upwards*/
1617 /* it also does constant folding, and paramater checking */
1618 /*-----------------------------------------------------------------*/
1619 ast *decorateType (ast *tree)
1627 /* if already has type then do nothing */
1628 if ( tree->decorated )
1631 tree->decorated = 1;
1633 /* print the line */
1634 /* if not block & function */
1635 if ( tree->type == EX_OP &&
1636 ( tree->opval.op != FUNCTION &&
1637 tree->opval.op != BLOCK &&
1638 tree->opval.op != NULLOP )) {
1639 filename = tree->filename ;
1640 lineno = tree->lineno ;
1643 /* if any child is an error | this one is an error do nothing */
1644 if ( tree->isError ||
1645 ( tree->left && tree->left->isError) ||
1646 ( tree->right && tree->right->isError ))
1649 /*------------------------------------------------------------------*/
1650 /*----------------------------*/
1651 /* leaf has been reached */
1652 /*----------------------------*/
1653 /* if this is of type value */
1654 /* just get the type */
1655 if ( tree->type == EX_VALUE ) {
1657 if ( IS_LITERAL(tree->opval.val->etype) ) {
1659 /* if this is a character array then declare it */
1660 if (IS_ARRAY(tree->opval.val->type))
1661 tree->opval.val = stringToSymbol(tree->opval.val);
1663 /* otherwise just copy the type information */
1664 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1665 if (funcInChain(tree->opval.val->type)) {
1666 tree->hasVargs = tree->opval.val->sym->hasVargs;
1667 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1672 if ( tree->opval.val->sym ) {
1673 /* if the undefined flag is set then give error message */
1674 if (tree->opval.val->sym->undefined ) {
1675 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1677 TTYPE(tree) = TETYPE(tree) =
1678 tree->opval.val->type = tree->opval.val->sym->type =
1679 tree->opval.val->etype = tree->opval.val->sym->etype =
1680 copyLinkChain(INTTYPE);
1684 /* if impilicit i.e. struct/union member then no type */
1685 if (tree->opval.val->sym->implicit )
1686 TTYPE(tree) = TETYPE(tree) = NULL ;
1690 /* else copy the type */
1691 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1693 /* and mark it as referenced */
1694 tree->opval.val->sym->isref = 1;
1695 /* if this is of type function or function pointer */
1696 if (funcInChain(tree->opval.val->type)) {
1697 tree->hasVargs = tree->opval.val->sym->hasVargs;
1698 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1708 /* if type link for the case of cast */
1709 if ( tree->type == EX_LINK ) {
1710 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1717 dtl = decorateType (tree->left);
1718 dtr = decorateType (tree->right);
1720 /* this is to take care of situations
1721 when the tree gets rewritten */
1722 if (dtl != tree->left)
1724 if (dtr != tree->right)
1728 /* depending on type of operator do */
1730 switch (tree->opval.op) {
1731 /*------------------------------------------------------------------*/
1732 /*----------------------------*/
1734 /*----------------------------*/
1737 /* determine which is the array & which the index */
1738 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1740 ast *tempTree = tree->left ;
1741 tree->left = tree->right ;
1742 tree->right= tempTree ;
1745 /* first check if this is a array or a pointer */
1746 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1747 werror(E_NEED_ARRAY_PTR,"[]");
1748 goto errorTreeReturn ;
1751 /* check if the type of the idx */
1752 if (!IS_INTEGRAL(RTYPE(tree))) {
1753 werror(E_IDX_NOT_INT);
1754 goto errorTreeReturn ;
1757 /* if the left is an rvalue then error */
1759 werror(E_LVALUE_REQUIRED,"array access");
1760 goto errorTreeReturn ;
1763 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1766 /*------------------------------------------------------------------*/
1767 /*----------------------------*/
1769 /*----------------------------*/
1771 /* if this is not a structure */
1772 if (!IS_STRUCT(LTYPE(tree))) {
1773 werror(E_STRUCT_UNION,".");
1774 goto errorTreeReturn ;
1776 TTYPE(tree) = structElemType (LTYPE(tree),
1777 (tree->right->type == EX_VALUE ?
1778 tree->right->opval.val : NULL ),&tree->args);
1779 TETYPE(tree) = getSpec(TTYPE(tree));
1782 /*------------------------------------------------------------------*/
1783 /*----------------------------*/
1784 /* struct/union pointer */
1785 /*----------------------------*/
1787 /* if not pointer to a structure */
1788 if (!IS_PTR(LTYPE(tree))) {
1790 goto errorTreeReturn ;
1793 if (!IS_STRUCT(LTYPE(tree)->next)) {
1794 werror(E_STRUCT_UNION,"->");
1795 goto errorTreeReturn ;
1798 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1799 (tree->right->type == EX_VALUE ?
1800 tree->right->opval.val : NULL ),&tree->args);
1801 TETYPE(tree) = getSpec(TTYPE(tree));
1804 /*------------------------------------------------------------------*/
1805 /*----------------------------*/
1806 /* ++/-- operation */
1807 /*----------------------------*/
1808 case INC_OP: /* incerement operator unary so left only */
1811 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1812 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1813 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1814 werror(E_CODE_WRITE,"++/--");
1823 /*------------------------------------------------------------------*/
1824 /*----------------------------*/
1826 /*----------------------------*/
1827 case '&': /* can be unary */
1828 /* if right is NULL then unary operation */
1829 if ( tree->right ) /* not an unary operation */ {
1831 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1832 werror(E_BITWISE_OP);
1833 werror(E_CONTINUE,"left & right types are ");
1834 printTypeChain(LTYPE(tree),stderr);
1835 fprintf(stderr,",");
1836 printTypeChain(RTYPE(tree),stderr);
1837 fprintf(stderr,"\n");
1838 goto errorTreeReturn ;
1841 /* if they are both literal */
1842 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1843 tree->type = EX_VALUE ;
1844 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1845 valFromType(RETYPE(tree)),'&');
1847 tree->right = tree->left = NULL;
1848 TETYPE(tree) = tree->opval.val->etype ;
1849 TTYPE(tree) = tree->opval.val->type;
1853 /* see if this is a GETHBIT operation if yes
1856 ast *otree = optimizeGetHbit(tree);
1859 return decorateType(otree);
1862 /* if right or left is literal then result of that type*/
1863 if (IS_LITERAL(RTYPE(tree))) {
1865 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1866 TETYPE(tree) = getSpec(TTYPE(tree));
1867 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1870 if (IS_LITERAL(LTYPE(tree))) {
1871 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1872 TETYPE(tree) = getSpec(TTYPE(tree));
1873 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1878 computeType (LTYPE(tree), RTYPE(tree));
1879 TETYPE(tree) = getSpec(TTYPE(tree));
1882 LRVAL(tree) = RRVAL(tree) = 1;
1886 /*------------------------------------------------------------------*/
1887 /*----------------------------*/
1889 /*----------------------------*/
1891 p->class = DECLARATOR;
1892 /* if bit field then error */
1893 if (IS_BITVAR(tree->left->etype)) {
1894 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1895 goto errorTreeReturn ;
1898 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1899 werror (E_ILLEGAL_ADDR,"address of register variable");
1900 goto errorTreeReturn;
1903 if (IS_FUNC(LTYPE(tree))) {
1904 werror(E_ILLEGAL_ADDR,"address of function");
1905 goto errorTreeReturn ;
1909 werror(E_LVALUE_REQUIRED,"address of");
1910 goto errorTreeReturn ;
1912 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1913 DCL_TYPE(p) = CPOINTER ;
1914 DCL_PTR_CONST(p) = port->mem.code_ro;
1917 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1918 DCL_TYPE(p) = FPOINTER;
1920 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1921 DCL_TYPE(p) = PPOINTER ;
1923 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1924 DCL_TYPE(p) = IPOINTER ;
1926 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1927 DCL_TYPE(p) = EEPPOINTER ;
1929 DCL_TYPE(p) = POINTER ;
1931 if (IS_AST_SYM_VALUE(tree->left)) {
1932 AST_SYMBOL(tree->left)->addrtaken = 1;
1933 AST_SYMBOL(tree->left)->allocreq = 1;
1936 p->next = LTYPE(tree);
1938 TETYPE(tree) = getSpec(TTYPE(tree));
1939 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1940 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1945 /*------------------------------------------------------------------*/
1946 /*----------------------------*/
1948 /*----------------------------*/
1950 /* if the rewrite succeeds then don't go any furthur */
1952 ast *wtree = optimizeRRCRLC ( tree );
1954 return decorateType(wtree) ;
1956 /*------------------------------------------------------------------*/
1957 /*----------------------------*/
1959 /*----------------------------*/
1961 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1962 werror(E_BITWISE_OP);
1963 werror(E_CONTINUE,"left & right types are ");
1964 printTypeChain(LTYPE(tree),stderr);
1965 fprintf(stderr,",");
1966 printTypeChain(RTYPE(tree),stderr);
1967 fprintf(stderr,"\n");
1968 goto errorTreeReturn ;
1971 /* if they are both literal then */
1972 /* rewrite the tree */
1973 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1974 tree->type = EX_VALUE ;
1975 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1976 valFromType(RETYPE(tree)),
1978 tree->right = tree->left = NULL;
1979 TETYPE(tree) = tree->opval.val->etype;
1980 TTYPE(tree) = tree->opval.val->type;
1983 LRVAL(tree) = RRVAL(tree) = 1;
1984 TETYPE(tree) = getSpec (TTYPE(tree) =
1985 computeType(LTYPE(tree),
1988 /*------------------------------------------------------------------*/
1989 /*----------------------------*/
1991 /*----------------------------*/
1993 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
1994 werror(E_INVALID_OP,"divide");
1995 goto errorTreeReturn ;
1997 /* if they are both literal then */
1998 /* rewrite the tree */
1999 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2000 tree->type = EX_VALUE ;
2001 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
2002 valFromType(RETYPE(tree)));
2003 tree->right = tree->left = NULL;
2004 TETYPE(tree) = getSpec(TTYPE(tree) =
2005 tree->opval.val->type);
2008 LRVAL(tree) = RRVAL(tree) = 1;
2009 TETYPE(tree) = getSpec (TTYPE(tree) =
2010 computeType(LTYPE(tree),
2014 /*------------------------------------------------------------------*/
2015 /*----------------------------*/
2017 /*----------------------------*/
2019 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
2020 werror(E_BITWISE_OP);
2021 werror(E_CONTINUE,"left & right types are ");
2022 printTypeChain(LTYPE(tree),stderr);
2023 fprintf(stderr,",");
2024 printTypeChain(RTYPE(tree),stderr);
2025 fprintf(stderr,"\n");
2026 goto errorTreeReturn ;
2028 /* if they are both literal then */
2029 /* rewrite the tree */
2030 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2031 tree->type = EX_VALUE ;
2032 tree->opval.val = valMod (valFromType(LETYPE(tree)),
2033 valFromType(RETYPE(tree)));
2034 tree->right = tree->left = NULL;
2035 TETYPE(tree) = getSpec(TTYPE(tree) =
2036 tree->opval.val->type);
2039 LRVAL(tree) = RRVAL(tree) = 1;
2040 TETYPE(tree) = getSpec (TTYPE(tree) =
2041 computeType(LTYPE(tree),
2045 /*------------------------------------------------------------------*/
2046 /*----------------------------*/
2047 /* address dereference */
2048 /*----------------------------*/
2049 case '*': /* can be unary : if right is null then unary operation */
2050 if ( ! tree->right ) {
2051 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2053 goto errorTreeReturn ;
2057 werror(E_LVALUE_REQUIRED,"pointer deref");
2058 goto errorTreeReturn ;
2060 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2061 LTYPE(tree)->next : NULL );
2062 TETYPE(tree) = getSpec(TTYPE(tree));
2063 tree->args = tree->left->args ;
2064 tree->hasVargs = tree->left->hasVargs ;
2065 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2069 /*------------------------------------------------------------------*/
2070 /*----------------------------*/
2071 /* multiplication */
2072 /*----------------------------*/
2073 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2074 werror(E_INVALID_OP,"multiplication");
2075 goto errorTreeReturn ;
2078 /* if they are both literal then */
2079 /* rewrite the tree */
2080 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2081 tree->type = EX_VALUE ;
2082 tree->opval.val = valMult (valFromType(LETYPE(tree)),
2083 valFromType(RETYPE(tree)));
2084 tree->right = tree->left = NULL;
2085 TETYPE(tree) = getSpec(TTYPE(tree) =
2086 tree->opval.val->type);
2090 /* if left is a literal exchange left & right */
2091 if (IS_LITERAL(LTYPE(tree))) {
2092 ast *tTree = tree->left ;
2093 tree->left = tree->right ;
2094 tree->right= tTree ;
2097 LRVAL(tree) = RRVAL(tree) = 1;
2098 TETYPE(tree) = getSpec (TTYPE(tree) =
2099 computeType(LTYPE(tree),
2103 /*------------------------------------------------------------------*/
2104 /*----------------------------*/
2105 /* unary '+' operator */
2106 /*----------------------------*/
2109 if ( ! tree->right ) {
2110 if (!IS_INTEGRAL(LTYPE(tree))) {
2111 werror(E_UNARY_OP,'+');
2112 goto errorTreeReturn ;
2115 /* if left is a literal then do it */
2116 if (IS_LITERAL(LTYPE(tree))) {
2117 tree->type = EX_VALUE ;
2118 tree->opval.val = valFromType(LETYPE(tree));
2120 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2124 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2128 /*------------------------------------------------------------------*/
2129 /*----------------------------*/
2131 /*----------------------------*/
2133 /* this is not a unary operation */
2134 /* if both pointers then problem */
2135 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2136 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2137 werror(E_PTR_PLUS_PTR);
2138 goto errorTreeReturn ;
2141 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2142 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2143 werror(E_PLUS_INVALID,"+");
2144 goto errorTreeReturn ;
2147 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2148 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2149 werror(E_PLUS_INVALID,"+");
2150 goto errorTreeReturn;
2152 /* if they are both literal then */
2153 /* rewrite the tree */
2154 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2155 tree->type = EX_VALUE ;
2156 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2157 valFromType(RETYPE(tree)));
2158 tree->right = tree->left = NULL;
2159 TETYPE(tree) = getSpec(TTYPE(tree) =
2160 tree->opval.val->type);
2164 /* if the right is a pointer or left is a literal
2165 xchange left & right */
2166 if (IS_ARRAY(RTYPE(tree)) ||
2167 IS_PTR(RTYPE(tree)) ||
2168 IS_LITERAL(LTYPE(tree))) {
2169 ast *tTree = tree->left ;
2170 tree->left = tree->right ;
2171 tree->right= tTree ;
2174 LRVAL(tree) = RRVAL(tree) = 1;
2175 /* if the left is a pointer */
2176 if (IS_PTR(LTYPE(tree)))
2177 TETYPE(tree) = getSpec(TTYPE(tree) =
2180 TETYPE(tree) = getSpec(TTYPE(tree) =
2181 computeType(LTYPE(tree),
2185 /*------------------------------------------------------------------*/
2186 /*----------------------------*/
2188 /*----------------------------*/
2189 case '-' : /* can be unary */
2190 /* if right is null then unary */
2191 if ( ! tree->right ) {
2193 if (!IS_ARITHMETIC(LTYPE(tree))) {
2194 werror(E_UNARY_OP,tree->opval.op);
2195 goto errorTreeReturn ;
2198 /* if left is a literal then do it */
2199 if (IS_LITERAL(LTYPE(tree))) {
2200 tree->type = EX_VALUE ;
2201 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2203 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2207 TTYPE(tree) = LTYPE(tree);
2211 /*------------------------------------------------------------------*/
2212 /*----------------------------*/
2214 /*----------------------------*/
2216 if (!(IS_PTR(LTYPE(tree)) ||
2217 IS_ARRAY(LTYPE(tree)) ||
2218 IS_ARITHMETIC(LTYPE(tree)))) {
2219 werror(E_PLUS_INVALID,"-");
2220 goto errorTreeReturn ;
2223 if (!(IS_PTR(RTYPE(tree)) ||
2224 IS_ARRAY(RTYPE(tree)) ||
2225 IS_ARITHMETIC(RTYPE(tree)))) {
2226 werror(E_PLUS_INVALID,"-");
2227 goto errorTreeReturn ;
2230 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2231 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2232 IS_INTEGRAL(RTYPE(tree))) ) {
2233 werror(E_PLUS_INVALID,"-");
2234 goto errorTreeReturn ;
2237 /* if they are both literal then */
2238 /* rewrite the tree */
2239 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2240 tree->type = EX_VALUE ;
2241 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2242 valFromType(RETYPE(tree)));
2243 tree->right = tree->left = NULL;
2244 TETYPE(tree) = getSpec(TTYPE(tree) =
2245 tree->opval.val->type);
2249 /* if the left & right are equal then zero */
2250 if (isAstEqual(tree->left,tree->right)) {
2251 tree->type = EX_VALUE;
2252 tree->left = tree->right = NULL;
2253 tree->opval.val = constVal("0");
2254 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2258 /* if both of them are pointers or arrays then */
2259 /* the result is going to be an integer */
2260 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2261 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2262 TETYPE(tree) = TTYPE(tree) = newIntLink();
2264 /* if only the left is a pointer */
2265 /* then result is a pointer */
2266 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2267 TETYPE(tree) = getSpec(TTYPE(tree) =
2270 TETYPE(tree) = getSpec (TTYPE(tree) =
2271 computeType(LTYPE(tree),
2273 LRVAL(tree) = RRVAL(tree) = 1;
2276 /*------------------------------------------------------------------*/
2277 /*----------------------------*/
2279 /*----------------------------*/
2281 /* can be only integral type */
2282 if (!IS_INTEGRAL(LTYPE(tree))) {
2283 werror(E_UNARY_OP,tree->opval.op);
2284 goto errorTreeReturn ;
2287 /* if left is a literal then do it */
2288 if (IS_LITERAL(LTYPE(tree))) {
2289 tree->type = EX_VALUE ;
2290 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2292 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2296 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2299 /*------------------------------------------------------------------*/
2300 /*----------------------------*/
2302 /*----------------------------*/
2304 /* can be pointer */
2305 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2306 !IS_PTR(LTYPE(tree)) &&
2307 !IS_ARRAY(LTYPE(tree))) {
2308 werror(E_UNARY_OP,tree->opval.op);
2309 goto errorTreeReturn ;
2312 /* if left is a literal then do it */
2313 if (IS_LITERAL(LTYPE(tree))) {
2314 tree->type = EX_VALUE ;
2315 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2317 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2321 TTYPE(tree) = TETYPE(tree) = newCharLink();
2324 /*------------------------------------------------------------------*/
2325 /*----------------------------*/
2327 /*----------------------------*/
2330 TTYPE(tree) = LTYPE(tree);
2331 TETYPE(tree) = LETYPE(tree);
2335 TTYPE(tree) = TETYPE(tree) = newCharLink();
2340 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2341 werror(E_SHIFT_OP_INVALID);
2342 werror(E_CONTINUE,"left & right types are ");
2343 printTypeChain(LTYPE(tree),stderr);
2344 fprintf(stderr,",");
2345 printTypeChain(RTYPE(tree),stderr);
2346 fprintf(stderr,"\n");
2347 goto errorTreeReturn ;
2350 /* if they are both literal then */
2351 /* rewrite the tree */
2352 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2353 tree->type = EX_VALUE ;
2354 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2355 valFromType(RETYPE(tree)),
2356 (tree->opval.op == LEFT_OP ? 1 : 0));
2357 tree->right = tree->left = NULL;
2358 TETYPE(tree) = getSpec(TTYPE(tree) =
2359 tree->opval.val->type);
2362 /* if only the right side is a literal & we are
2363 shifting more than size of the left operand then zero */
2364 if (IS_LITERAL(RTYPE(tree)) &&
2365 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2366 (getSize(LTYPE(tree))*8)) {
2367 werror(W_SHIFT_CHANGED,
2368 (tree->opval.op == LEFT_OP ? "left" : "right"));
2369 tree->type = EX_VALUE;
2370 tree->left = tree->right = NULL;
2371 tree->opval.val = constVal("0");
2372 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2375 LRVAL(tree) = RRVAL(tree) = 1;
2376 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2377 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2379 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2383 /*------------------------------------------------------------------*/
2384 /*----------------------------*/
2386 /*----------------------------*/
2387 case CAST: /* change the type */
2388 /* cannot cast to an aggregate type */
2389 if (IS_AGGREGATE(LTYPE(tree))) {
2390 werror(E_CAST_ILLEGAL);
2391 goto errorTreeReturn ;
2394 /* if the right is a literal replace the tree */
2395 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2396 tree->type = EX_VALUE ;
2398 valCastLiteral(LTYPE(tree),
2399 floatFromVal(valFromType(RETYPE(tree))));
2402 TTYPE(tree) = tree->opval.val->type;
2403 tree->values.literalFromCast = 1;
2406 TTYPE(tree) = LTYPE(tree);
2410 TETYPE(tree) = getSpec(TTYPE(tree));
2414 /*------------------------------------------------------------------*/
2415 /*----------------------------*/
2416 /* logical &&, || */
2417 /*----------------------------*/
2420 /* each must me arithmetic type or be a pointer */
2421 if (!IS_PTR(LTYPE(tree)) &&
2422 !IS_ARRAY(LTYPE(tree)) &&
2423 !IS_INTEGRAL(LTYPE(tree))) {
2424 werror(E_COMPARE_OP);
2425 goto errorTreeReturn ;
2428 if (!IS_PTR(RTYPE(tree)) &&
2429 !IS_ARRAY(RTYPE(tree)) &&
2430 !IS_INTEGRAL(RTYPE(tree))) {
2431 werror(E_COMPARE_OP);
2432 goto errorTreeReturn ;
2434 /* if they are both literal then */
2435 /* rewrite the tree */
2436 if (IS_LITERAL(RTYPE(tree)) &&
2437 IS_LITERAL(LTYPE(tree))) {
2438 tree->type = EX_VALUE ;
2439 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2440 valFromType(RETYPE(tree)),
2442 tree->right = tree->left = NULL;
2443 TETYPE(tree) = getSpec(TTYPE(tree) =
2444 tree->opval.val->type);
2447 LRVAL(tree) = RRVAL(tree) = 1;
2448 TTYPE(tree) = TETYPE(tree) = newCharLink();
2451 /*------------------------------------------------------------------*/
2452 /*----------------------------*/
2453 /* comparison operators */
2454 /*----------------------------*/
2462 ast *lt = optimizeCompare(tree);
2468 /* if they are pointers they must be castable */
2469 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2470 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2471 werror(E_COMPARE_OP);
2472 fprintf(stderr,"comparing type ");
2473 printTypeChain(LTYPE(tree),stderr);
2474 fprintf(stderr,"to type ");
2475 printTypeChain(RTYPE(tree),stderr);
2476 fprintf(stderr,"\n");
2477 goto errorTreeReturn ;
2480 /* else they should be promotable to one another */
2482 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2483 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2485 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2486 werror(E_COMPARE_OP);
2487 fprintf(stderr,"comparing type ");
2488 printTypeChain(LTYPE(tree),stderr);
2489 fprintf(stderr,"to type ");
2490 printTypeChain(RTYPE(tree),stderr);
2491 fprintf(stderr,"\n");
2492 goto errorTreeReturn ;
2496 /* if they are both literal then */
2497 /* rewrite the tree */
2498 if (IS_LITERAL(RTYPE(tree)) &&
2499 IS_LITERAL(LTYPE(tree))) {
2500 tree->type = EX_VALUE ;
2501 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2502 valFromType(RETYPE(tree)),
2504 tree->right = tree->left = NULL;
2505 TETYPE(tree) = getSpec(TTYPE(tree) =
2506 tree->opval.val->type);
2509 LRVAL(tree) = RRVAL(tree) = 1;
2510 TTYPE(tree) = TETYPE(tree) = newCharLink();
2513 /*------------------------------------------------------------------*/
2514 /*----------------------------*/
2516 /*----------------------------*/
2517 case SIZEOF : /* evaluate wihout code generation */
2518 /* change the type to a integer */
2519 tree->type = EX_VALUE;
2520 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2521 tree->opval.val = constVal(buffer);
2522 tree->right = tree->left = NULL;
2523 TETYPE(tree) = getSpec(TTYPE(tree) =
2524 tree->opval.val->type);
2527 /*------------------------------------------------------------------*/
2528 /*----------------------------*/
2529 /* conditional operator '?' */
2530 /*----------------------------*/
2532 /* the type is one on the left */
2533 TTYPE(tree) = LTYPE(tree);
2534 TETYPE(tree)= getSpec (TTYPE(tree));
2538 /* if they don't match we have a problem */
2539 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2540 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2541 goto errorTreeReturn ;
2544 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2545 TETYPE(tree)= getSpec(TTYPE(tree));
2549 /*------------------------------------------------------------------*/
2550 /*----------------------------*/
2551 /* assignment operators */
2552 /*----------------------------*/
2555 /* for these it must be both must be integral */
2556 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2557 !IS_ARITHMETIC(RTYPE(tree))) {
2558 werror (E_OPS_INTEGRAL);
2559 goto errorTreeReturn ;
2562 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2564 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2565 werror(E_CODE_WRITE," ");
2568 werror(E_LVALUE_REQUIRED,"*= or /=");
2569 goto errorTreeReturn ;
2582 /* for these it must be both must be integral */
2583 if (!IS_INTEGRAL(LTYPE(tree)) ||
2584 !IS_INTEGRAL(RTYPE(tree))) {
2585 werror (E_OPS_INTEGRAL);
2586 goto errorTreeReturn ;
2589 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2591 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2592 werror(E_CODE_WRITE," ");
2595 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2596 goto errorTreeReturn ;
2604 /*------------------------------------------------------------------*/
2605 /*----------------------------*/
2607 /*----------------------------*/
2609 if (!(IS_PTR(LTYPE(tree)) ||
2610 IS_ARITHMETIC(LTYPE(tree)))) {
2611 werror(E_PLUS_INVALID,"-=");
2612 goto errorTreeReturn ;
2615 if (!(IS_PTR(RTYPE(tree)) ||
2616 IS_ARITHMETIC(RTYPE(tree)))) {
2617 werror(E_PLUS_INVALID,"-=");
2618 goto errorTreeReturn ;
2621 TETYPE(tree) = getSpec (TTYPE(tree) =
2622 computeType(LTYPE(tree),
2625 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2626 werror(E_CODE_WRITE," ");
2629 werror(E_LVALUE_REQUIRED,"-=");
2630 goto errorTreeReturn ;
2638 /*------------------------------------------------------------------*/
2639 /*----------------------------*/
2641 /*----------------------------*/
2643 /* this is not a unary operation */
2644 /* if both pointers then problem */
2645 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2646 werror(E_PTR_PLUS_PTR);
2647 goto errorTreeReturn ;
2650 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2651 werror(E_PLUS_INVALID,"+=");
2652 goto errorTreeReturn ;
2655 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2656 werror(E_PLUS_INVALID,"+=");
2657 goto errorTreeReturn;
2660 TETYPE(tree) = getSpec (TTYPE(tree) =
2661 computeType(LTYPE(tree),
2664 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2665 werror(E_CODE_WRITE," ");
2668 werror(E_LVALUE_REQUIRED,"+=");
2669 goto errorTreeReturn ;
2672 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2673 tree->opval.op = '=';
2679 /*------------------------------------------------------------------*/
2680 /*----------------------------*/
2681 /* straight assignemnt */
2682 /*----------------------------*/
2684 /* cannot be an aggregate */
2685 if (IS_AGGREGATE(LTYPE(tree))) {
2686 werror(E_AGGR_ASSIGN);
2687 goto errorTreeReturn;
2690 /* they should either match or be castable */
2691 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2692 werror(E_TYPE_MISMATCH,"assignment"," ");
2693 fprintf(stderr,"type --> '");
2694 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2695 fprintf(stderr,"assigned to type --> '");
2696 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2697 goto errorTreeReturn ;
2700 /* if the left side of the tree is of type void
2701 then report error */
2702 if (IS_VOID(LTYPE(tree))) {
2703 werror(E_CAST_ZERO);
2704 fprintf(stderr,"type --> '");
2705 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2706 fprintf(stderr,"assigned to type --> '");
2707 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2710 /* extra checks for pointer types */
2711 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2712 !IS_GENPTR(LTYPE(tree))) {
2713 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2714 werror(W_PTR_ASSIGN);
2717 TETYPE(tree) = getSpec(TTYPE(tree) =
2721 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2722 werror(E_CODE_WRITE," ");
2725 werror(E_LVALUE_REQUIRED,"=");
2726 goto errorTreeReturn ;
2733 /*------------------------------------------------------------------*/
2734 /*----------------------------*/
2735 /* comma operator */
2736 /*----------------------------*/
2738 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2741 /*------------------------------------------------------------------*/
2742 /*----------------------------*/
2744 /*----------------------------*/
2749 if (processParms (tree->left,
2751 tree->right,&parmNumber))
2752 goto errorTreeReturn ;
2754 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2755 tree->left->args = reverseVal(tree->left->args);
2756 reverseParms(tree->right);
2759 tree->args = tree->left->args ;
2760 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2763 /*------------------------------------------------------------------*/
2764 /*----------------------------*/
2765 /* return statement */
2766 /*----------------------------*/
2771 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2772 werror(E_RETURN_MISMATCH);
2773 goto errorTreeReturn ;
2776 if (IS_VOID(currFunc->type->next)
2778 !IS_VOID(RTYPE(tree))) {
2779 werror(E_FUNC_VOID);
2780 goto errorTreeReturn ;
2783 /* if there is going to be a casing required then add it */
2784 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2786 #ifdef DEMAND_INTEGER_PROMOTION
2787 if (IS_INTEGRAL(currFunc->type->next))
2789 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2795 decorateType(newNode(CAST,
2796 newAst_LINK(copyLinkChain(currFunc->type->next)),
2806 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2807 werror(E_VOID_FUNC,currFunc->name);
2808 goto errorTreeReturn ;
2811 TTYPE(tree) = TETYPE(tree) = NULL ;
2814 /*------------------------------------------------------------------*/
2815 /*----------------------------*/
2816 /* switch statement */
2817 /*----------------------------*/
2819 /* the switch value must be an integer */
2820 if (!IS_INTEGRAL(LTYPE(tree))) {
2821 werror (E_SWITCH_NON_INTEGER);
2822 goto errorTreeReturn ;
2825 TTYPE(tree) = TETYPE(tree) = NULL ;
2828 /*------------------------------------------------------------------*/
2829 /*----------------------------*/
2831 /*----------------------------*/
2833 tree->left = backPatchLabels(tree->left,
2836 TTYPE(tree) = TETYPE(tree) = NULL;
2839 /*------------------------------------------------------------------*/
2840 /*----------------------------*/
2842 /*----------------------------*/
2845 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2846 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2847 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2849 /* if the for loop is reversible then
2850 reverse it otherwise do what we normally
2856 if (isLoopReversible (tree,&sym,&init,&end))
2857 return reverseLoop (tree,sym,init,end);
2859 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2860 AST_FOR(tree,continueLabel) ,
2861 AST_FOR(tree,falseLabel) ,
2862 AST_FOR(tree,condLabel) ,
2863 AST_FOR(tree,initExpr) ,
2864 AST_FOR(tree,condExpr) ,
2865 AST_FOR(tree,loopExpr),
2869 TTYPE(tree) = TETYPE(tree) = NULL ;
2873 /* some error found this tree will be killed */
2875 TTYPE(tree) = TETYPE(tree) = newCharLink();
2876 tree->opval.op = NULLOP ;
2882 /*-----------------------------------------------------------------*/
2883 /* sizeofOp - processes size of operation */
2884 /*-----------------------------------------------------------------*/
2885 value *sizeofOp( sym_link *type)
2889 /* get the size and convert it to character */
2890 sprintf (buff,"%d", getSize(type));
2892 /* now convert into value */
2893 return constVal (buff);
2897 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2898 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2899 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2900 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2901 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2902 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2903 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2905 /*-----------------------------------------------------------------*/
2906 /* backPatchLabels - change and or not operators to flow control */
2907 /*-----------------------------------------------------------------*/
2908 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2914 if ( ! (IS_ANDORNOT(tree)))
2917 /* if this an and */
2919 static int localLbl = 0 ;
2920 symbol *localLabel ;
2922 sprintf (buffer,"_and_%d",localLbl++);
2923 localLabel = newSymbol(buffer,NestLevel);
2925 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2927 /* if left is already a IFX then just change the if true label in that */
2928 if (!IS_IFX(tree->left))
2929 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2931 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2932 /* right is a IFX then just join */
2933 if (IS_IFX(tree->right))
2934 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2936 tree->right = createLabel(localLabel,tree->right);
2937 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2939 return newNode(NULLOP,tree->left,tree->right);
2942 /* if this is an or operation */
2944 static int localLbl = 0 ;
2945 symbol *localLabel ;
2947 sprintf (buffer,"_or_%d",localLbl++);
2948 localLabel = newSymbol(buffer,NestLevel);
2950 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2952 /* if left is already a IFX then just change the if true label in that */
2953 if (!IS_IFX(tree->left))
2954 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2956 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2957 /* right is a IFX then just join */
2958 if (IS_IFX(tree->right))
2959 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2961 tree->right = createLabel(localLabel,tree->right);
2962 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2964 return newNode(NULLOP,tree->left,tree->right);
2969 int wasnot = IS_NOT(tree->left);
2970 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2972 /* if the left is already a IFX */
2973 if ( ! IS_IFX(tree->left) )
2974 tree->left = newNode (IFX,tree->left,NULL);
2977 tree->left->trueLabel = trueLabel ;
2978 tree->left->falseLabel= falseLabel ;
2980 tree->left->trueLabel = falseLabel ;
2981 tree->left->falseLabel= trueLabel ;
2987 tree->trueLabel = trueLabel ;
2988 tree->falseLabel= falseLabel;
2995 /*-----------------------------------------------------------------*/
2996 /* createBlock - create expression tree for block */
2997 /*-----------------------------------------------------------------*/
2998 ast *createBlock ( symbol *decl, ast *body )
3002 /* if the block has nothing */
3006 ex = newNode(BLOCK,NULL,body);
3007 ex->values.sym = decl ;
3009 ex->right = ex->right ;
3015 /*-----------------------------------------------------------------*/
3016 /* createLabel - creates the expression tree for labels */
3017 /*-----------------------------------------------------------------*/
3018 ast *createLabel ( symbol *label, ast *stmnt )
3021 char name[SDCC_NAME_MAX+1];
3024 /* must create fresh symbol if the symbol name */
3025 /* exists in the symbol table, since there can */
3026 /* be a variable with the same name as the labl */
3027 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
3028 (csym->level == label->level))
3029 label = newSymbol(label->name,label->level);
3031 /* change the name before putting it in add _*/
3032 sprintf (name,"%s",label->name);
3034 /* put the label in the LabelSymbol table */
3035 /* but first check if a label of the same */
3037 if ( (csym = findSym(LabelTab,NULL,name)))
3038 werror(E_DUPLICATE_LABEL,label->name);
3040 addSym (LabelTab, label, name,label->level,0);
3043 label->key = labelKey++ ;
3044 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3050 /*-----------------------------------------------------------------*/
3051 /* createCase - generates the parsetree for a case statement */
3052 /*-----------------------------------------------------------------*/
3053 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
3055 char caseLbl[SDCC_NAME_MAX+1];
3059 /* if the switch statement does not exist */
3060 /* then case is out of context */
3062 werror(E_CASE_CONTEXT);
3066 caseVal = decorateType(resolveSymbols(caseVal));
3067 /* if not a constant then error */
3068 if (!IS_LITERAL(caseVal->ftype)) {
3069 werror(E_CASE_CONSTANT);
3073 /* if not a integer than error */
3074 if (!IS_INTEGRAL(caseVal->ftype)) {
3075 werror(E_CASE_NON_INTEGER);
3079 /* find the end of the switch values chain */
3080 if (!(val = swStat->values.switchVals.swVals))
3081 swStat->values.switchVals.swVals = caseVal->opval.val ;
3083 /* also order the cases according to value */
3085 int cVal = (int) floatFromVal(caseVal->opval.val);
3086 while (val && (int) floatFromVal(val) < cVal) {
3091 /* if we reached the end then */
3093 pval->next = caseVal->opval.val;
3095 /* we found a value greater than */
3096 /* the current value we must add this */
3097 /* before the value */
3098 caseVal->opval.val->next = val;
3100 /* if this was the first in chain */
3101 if (swStat->values.switchVals.swVals == val)
3102 swStat->values.switchVals.swVals =
3105 pval->next = caseVal->opval.val;
3110 /* create the case label */
3111 sprintf(caseLbl,"_case_%d_%d",
3112 swStat->values.switchVals.swNum,
3113 (int) floatFromVal(caseVal->opval.val));
3115 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3120 /*-----------------------------------------------------------------*/
3121 /* createDefault - creates the parse tree for the default statement*/
3122 /*-----------------------------------------------------------------*/
3123 ast *createDefault (ast *swStat, ast *stmnt)
3125 char defLbl[SDCC_NAME_MAX+1];
3127 /* if the switch statement does not exist */
3128 /* then case is out of context */
3130 werror(E_CASE_CONTEXT);
3134 /* turn on the default flag */
3135 swStat->values.switchVals.swDefault = 1 ;
3137 /* create the label */
3138 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3139 return createLabel(newSymbol(defLbl,0),stmnt);
3142 /*-----------------------------------------------------------------*/
3143 /* createIf - creates the parsetree for the if statement */
3144 /*-----------------------------------------------------------------*/
3145 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3147 static int Lblnum = 0 ;
3149 symbol *ifTrue , *ifFalse, *ifEnd ;
3151 /* if neither exists */
3152 if (! elseBody && !ifBody)
3155 /* create the labels */
3156 sprintf (buffer,"_iffalse_%d",Lblnum);
3157 ifFalse = newSymbol (buffer,NestLevel);
3158 /* if no else body then end == false */
3162 sprintf (buffer,"_ifend_%d",Lblnum);
3163 ifEnd = newSymbol (buffer,NestLevel);
3166 sprintf (buffer,"_iftrue_%d",Lblnum);
3167 ifTrue = newSymbol (buffer,NestLevel);
3171 /* attach the ifTrue label to the top of it body */
3172 ifBody = createLabel(ifTrue,ifBody);
3173 /* attach a goto end to the ifBody if else is present */
3175 ifBody = newNode(NULLOP,ifBody,
3177 newAst_VALUE(symbolVal(ifEnd)),
3179 /* put the elseLabel on the else body */
3180 elseBody = createLabel (ifFalse,elseBody);
3181 /* out the end at the end of the body */
3182 elseBody = newNode(NULLOP,
3184 createLabel(ifEnd,NULL));
3187 ifBody = newNode(NULLOP,ifBody,
3188 createLabel(ifFalse,NULL));
3190 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3191 if (IS_IFX(condAst))
3194 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3196 return newNode(NULLOP,ifTree,
3197 newNode(NULLOP,ifBody,elseBody));
3201 /*-----------------------------------------------------------------*/
3202 /* createDo - creates parse tree for do */
3205 /* _docontinue_n: */
3206 /* condition_expression +-> trueLabel -> _dobody_n */
3208 /* +-> falseLabel-> _dobreak_n */
3210 /*-----------------------------------------------------------------*/
3211 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3212 symbol *falseLabel, ast *condAst, ast *doBody )
3217 /* if the body does not exist then it is simple */
3219 condAst = backPatchLabels(condAst,continueLabel,NULL);
3220 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3221 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3222 doTree->trueLabel = continueLabel ;
3223 doTree->falseLabel= NULL ;
3227 /* otherwise we have a body */
3228 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3230 /* attach the body label to the top */
3231 doBody = createLabel(trueLabel,doBody);
3232 /* attach the continue label to end of body */
3233 doBody = newNode(NULLOP, doBody,
3234 createLabel(continueLabel,NULL));
3236 /* now put the break label at the end */
3237 if (IS_IFX(condAst))
3240 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3242 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3244 /* putting it together */
3245 return newNode(NULLOP,doBody,doTree);
3248 /*-----------------------------------------------------------------*/
3249 /* createFor - creates parse tree for 'for' statement */
3252 /* condExpr +-> trueLabel -> _forbody_n */
3254 /* +-> falseLabel-> _forbreak_n */
3257 /* _forcontinue_n: */
3259 /* goto _forcond_n ; */
3261 /*-----------------------------------------------------------------*/
3262 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3263 symbol *falseLabel,symbol *condLabel ,
3264 ast *initExpr, ast *condExpr, ast *loopExpr,
3269 /* if loopexpression not present then we can generate it */
3270 /* the same way as a while */
3272 return newNode(NULLOP,initExpr,
3273 createWhile (trueLabel, continueLabel,
3274 falseLabel,condExpr, forBody ));
3275 /* vanilla for statement */
3276 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3278 if (condExpr && !IS_IFX(condExpr))
3279 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3282 /* attach condition label to condition */
3283 condExpr = createLabel(condLabel,condExpr);
3285 /* attach body label to body */
3286 forBody = createLabel(trueLabel,forBody);
3288 /* attach continue to forLoop expression & attach */
3289 /* goto the forcond @ and of loopExpression */
3290 loopExpr = createLabel(continueLabel,
3294 newAst_VALUE(symbolVal(condLabel)),
3296 /* now start putting them together */
3297 forTree = newNode(NULLOP,initExpr,condExpr);
3298 forTree = newNode(NULLOP,forTree,forBody);
3299 forTree = newNode(NULLOP,forTree,loopExpr);
3300 /* finally add the break label */
3301 forTree = newNode(NULLOP,forTree,
3302 createLabel(falseLabel,NULL));
3306 /*-----------------------------------------------------------------*/
3307 /* createWhile - creates parse tree for while statement */
3308 /* the while statement will be created as follows */
3310 /* _while_continue_n: */
3311 /* condition_expression +-> trueLabel -> _while_boby_n */
3313 /* +-> falseLabel -> _while_break_n*/
3314 /* _while_body_n: */
3316 /* goto _while_continue_n */
3317 /* _while_break_n: */
3318 /*-----------------------------------------------------------------*/
3319 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3320 symbol *falseLabel,ast *condExpr, ast *whileBody )
3324 /* put the continue label */
3325 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3326 condExpr = createLabel(continueLabel,condExpr);
3327 condExpr->lineno = 0;
3329 /* put the body label in front of the body */
3330 whileBody = createLabel(trueLabel,whileBody);
3331 whileBody->lineno = 0;
3332 /* put a jump to continue at the end of the body */
3333 /* and put break label at the end of the body */
3334 whileBody = newNode(NULLOP,
3337 newAst_VALUE(symbolVal(continueLabel)),
3338 createLabel(falseLabel,NULL)));
3340 /* put it all together */
3341 if ( IS_IFX(condExpr) )
3342 whileTree = condExpr ;
3344 whileTree = newNode (IFX, condExpr,NULL );
3345 /* put the true & false labels in place */
3346 whileTree->trueLabel = trueLabel ;
3347 whileTree->falseLabel= falseLabel;
3350 return newNode(NULLOP,whileTree,whileBody );
3353 /*-----------------------------------------------------------------*/
3354 /* optimizeGetHbit - get highest order bit of the expression */
3355 /*-----------------------------------------------------------------*/
3356 ast *optimizeGetHbit (ast *tree)
3359 /* if this is not a bit and */
3360 if (!IS_BITAND(tree))
3363 /* will look for tree of the form
3364 ( expr >> ((sizeof expr) -1) ) & 1 */
3365 if (!IS_AST_LIT_VALUE(tree->right))
3368 if (AST_LIT_VALUE(tree->right) != 1)
3371 if (!IS_RIGHT_OP(tree->left))
3374 if (!IS_AST_LIT_VALUE(tree->left->right))
3377 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3378 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3381 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3385 /*-----------------------------------------------------------------*/
3386 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3387 /*-----------------------------------------------------------------*/
3388 ast *optimizeRRCRLC ( ast *root )
3390 /* will look for trees of the form
3391 (?expr << 1) | (?expr >> 7) or
3392 (?expr >> 7) | (?expr << 1) will make that
3393 into a RLC : operation ..
3395 (?expr >> 1) | (?expr << 7) or
3396 (?expr << 7) | (?expr >> 1) will make that
3397 into a RRC operation
3398 note : by 7 I mean (number of bits required to hold the
3400 /* if the root operations is not a | operation the not */
3401 if (!IS_BITOR(root))
3404 /* I have to think of a better way to match patterns this sucks */
3405 /* that aside let start looking for the first case : I use a the
3406 negative check a lot to improve the efficiency */
3407 /* (?expr << 1) | (?expr >> 7) */
3408 if (IS_LEFT_OP(root->left) &&
3409 IS_RIGHT_OP(root->right) ) {
3411 if (!SPEC_USIGN(TETYPE(root->left->left)))
3414 if (!IS_AST_LIT_VALUE(root->left->right) ||
3415 !IS_AST_LIT_VALUE(root->right->right))
3418 /* make sure it is the same expression */
3419 if (!isAstEqual(root->left->left,
3423 if (AST_LIT_VALUE(root->left->right) != 1 )
3426 if (AST_LIT_VALUE(root->right->right) !=
3427 (getSize(TTYPE(root->left->left))*8 - 1))
3430 /* whew got the first case : create the AST */
3431 return newNode(RLC,root->left->left,NULL);
3435 /* check for second case */
3436 /* (?expr >> 7) | (?expr << 1) */
3437 if (IS_LEFT_OP(root->right) &&
3438 IS_RIGHT_OP(root->left) ) {
3440 if (!SPEC_USIGN(TETYPE(root->left->left)))
3443 if (!IS_AST_LIT_VALUE(root->left->right) ||
3444 !IS_AST_LIT_VALUE(root->right->right))
3447 /* make sure it is the same symbol */
3448 if (!isAstEqual(root->left->left,
3452 if (AST_LIT_VALUE(root->right->right) != 1 )
3455 if (AST_LIT_VALUE(root->left->right) !=
3456 (getSize(TTYPE(root->left->left))*8 - 1))
3459 /* whew got the first case : create the AST */
3460 return newNode(RLC,root->left->left,NULL);
3465 /* third case for RRC */
3466 /* (?symbol >> 1) | (?symbol << 7) */
3467 if (IS_LEFT_OP(root->right) &&
3468 IS_RIGHT_OP(root->left) ) {
3470 if (!SPEC_USIGN(TETYPE(root->left->left)))
3473 if (!IS_AST_LIT_VALUE(root->left->right) ||
3474 !IS_AST_LIT_VALUE(root->right->right))
3477 /* make sure it is the same symbol */
3478 if (!isAstEqual(root->left->left,
3482 if (AST_LIT_VALUE(root->left->right) != 1 )
3485 if (AST_LIT_VALUE(root->right->right) !=
3486 (getSize(TTYPE(root->left->left))*8 - 1))
3489 /* whew got the first case : create the AST */
3490 return newNode(RRC,root->left->left,NULL);
3494 /* fourth and last case for now */
3495 /* (?symbol << 7) | (?symbol >> 1) */
3496 if (IS_RIGHT_OP(root->right) &&
3497 IS_LEFT_OP(root->left) ) {
3499 if (!SPEC_USIGN(TETYPE(root->left->left)))
3502 if (!IS_AST_LIT_VALUE(root->left->right) ||
3503 !IS_AST_LIT_VALUE(root->right->right))
3506 /* make sure it is the same symbol */
3507 if (!isAstEqual(root->left->left,
3511 if (AST_LIT_VALUE(root->right->right) != 1 )
3514 if (AST_LIT_VALUE(root->left->right) !=
3515 (getSize(TTYPE(root->left->left))*8 - 1))
3518 /* whew got the first case : create the AST */
3519 return newNode(RRC,root->left->left,NULL);
3523 /* not found return root */
3527 /*-----------------------------------------------------------------*/
3528 /* optimizeCompare - otimizes compares for bit variables */
3529 /*-----------------------------------------------------------------*/
3530 ast *optimizeCompare ( ast *root )
3532 ast *optExpr = NULL;
3535 unsigned int litValue ;
3537 /* if nothing then return nothing */
3541 /* if not a compare op then do leaves */
3542 if (!IS_COMPARE_OP(root)) {
3543 root->left = optimizeCompare (root->left);
3544 root->right= optimizeCompare (root->right);
3548 /* if left & right are the same then depending
3549 of the operation do */
3550 if (isAstEqual(root->left,root->right)) {
3551 switch (root->opval.op) {
3555 optExpr = newAst_VALUE(constVal("0"));
3560 optExpr = newAst_VALUE(constVal("1"));
3564 return decorateType(optExpr);
3567 vleft = (root->left->type == EX_VALUE ?
3568 root->left->opval.val : NULL );
3570 vright = (root->right->type == EX_VALUE ?
3571 root->right->opval.val : NULL);
3573 /* if left is a BITVAR in BITSPACE */
3574 /* and right is a LITERAL then opt-*/
3575 /* imize else do nothing */
3576 if (vleft && vright &&
3577 IS_BITVAR(vleft->etype) &&
3578 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3579 IS_LITERAL(vright->etype)) {
3581 /* if right side > 1 then comparison may never succeed */
3582 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3583 werror(W_BAD_COMPARE);
3588 switch (root->opval.op) {
3589 case '>' : /* bit value greater than 1 cannot be */
3590 werror(W_BAD_COMPARE);
3594 case '<' : /* bit value < 1 means 0 */
3596 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3599 case LE_OP : /* bit value <= 1 means no check */
3600 optExpr = newAst_VALUE(vright);
3603 case GE_OP : /* bit value >= 1 means only check for = */
3605 optExpr = newAst_VALUE(vleft);
3608 } else { /* literal is zero */
3609 switch (root->opval.op) {
3610 case '<' : /* bit value < 0 cannot be */
3611 werror(W_BAD_COMPARE);
3615 case '>' : /* bit value > 0 means 1 */
3617 optExpr = newAst_VALUE(vleft);
3620 case LE_OP : /* bit value <= 0 means no check */
3621 case GE_OP : /* bit value >= 0 means no check */
3622 werror(W_BAD_COMPARE);
3626 case EQ_OP : /* bit == 0 means ! of bit */
3627 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3631 return decorateType(resolveSymbols(optExpr));
3632 } /* end-of-if of BITVAR */
3637 /*-----------------------------------------------------------------*/
3638 /* addSymToBlock : adds the symbol to the first block we find */
3639 /*-----------------------------------------------------------------*/
3640 void addSymToBlock (symbol *sym, ast *tree)
3642 /* reached end of tree or a leaf */
3643 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3647 if (IS_AST_OP(tree) &&
3648 tree->opval.op == BLOCK ) {
3650 symbol *lsym = copySymbol(sym);
3652 lsym->next = AST_VALUES(tree,sym);
3653 AST_VALUES(tree,sym) = lsym ;
3657 addSymToBlock(sym,tree->left);
3658 addSymToBlock(sym,tree->right);
3661 /*-----------------------------------------------------------------*/
3662 /* processRegParms - do processing for register parameters */
3663 /*-----------------------------------------------------------------*/
3664 static void processRegParms (value *args, ast *body)
3667 if (IS_REGPARM(args->etype))
3668 addSymToBlock(args->sym,body);
3673 /*-----------------------------------------------------------------*/
3674 /* resetParmKey - resets the operandkeys for the symbols */
3675 /*-----------------------------------------------------------------*/
3676 DEFSETFUNC(resetParmKey)
3687 /*-----------------------------------------------------------------*/
3688 /* createFunction - This is the key node that calls the iCode for */
3689 /* generating the code for a function. Note code */
3690 /* is generated function by function, later when */
3691 /* add inter-procedural analysis this will change */
3692 /*-----------------------------------------------------------------*/
3693 ast *createFunction (symbol *name, ast *body )
3699 iCode *piCode = NULL;
3701 /* if check function return 0 then some problem */
3702 if (checkFunction (name) == 0)
3705 /* create a dummy block if none exists */
3707 body = newNode(BLOCK,NULL,NULL);
3711 /* check if the function name already in the symbol table */
3712 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3714 /* special case for compiler defined functions
3715 we need to add the name to the publics list : this
3716 actually means we are now compiling the compiler
3719 addSet(&publics,name);
3724 allocVariables(name);
3726 name->lastLine = yylineno;
3728 processFuncArgs(currFunc,0);
3730 /* set the stack pointer */
3731 /* PENDING: check this for the mcs51 */
3732 stackPtr = -port->stack.direction * port->stack.call_overhead;
3733 if (IS_ISR(name->etype))
3734 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3735 if (IS_RENT(name->etype) || options.stackAuto)
3736 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3738 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3740 fetype = getSpec(name->type); /* get the specifier for the function */
3741 /* if this is a reentrant function then */
3742 if (IS_RENT(fetype))
3745 allocParms (name->args); /* allocate the parameters */
3747 /* do processing for parameters that are passed in registers */
3748 processRegParms (name->args,body);
3750 /* set the stack pointer */
3754 /* allocate & autoinit the block variables */
3755 processBlockVars (body, &stack,ALLOCATE);
3757 /* save the stack information */
3758 if (options.useXstack)
3759 name->xstack = SPEC_STAK(fetype) = stack;
3761 name->stack = SPEC_STAK(fetype) = stack;
3763 /* name needs to be mangled */
3764 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3766 body = resolveSymbols(body); /* resolve the symbols */
3767 body = decorateType (body); /* propagateType & do semantic checks */
3769 ex = newAst_VALUE(symbolVal(name)); /* create name */
3770 ex = newNode (FUNCTION,ex,body);
3771 ex->values.args = name->args ;
3774 werror(E_FUNC_NO_CODE,name->name);
3778 /* create the node & generate intermediate code */
3779 codeOutFile = code->oFile;
3780 piCode = iCodeFromAst(ex);
3783 werror(E_FUNC_NO_CODE,name->name);
3787 eBBlockFromiCode(piCode);
3789 /* if there are any statics then do them */
3791 codeOutFile = statsg->oFile;
3792 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3798 /* dealloc the block variables */
3799 processBlockVars(body, &stack,DEALLOCATE);
3800 /* deallocate paramaters */
3801 deallocParms(name->args);
3803 if (IS_RENT(fetype))
3806 /* we are done freeup memory & cleanup */
3811 addSet(&operKeyReset,name);
3812 applyToSet(operKeyReset,resetParmKey);
3814 if (options.debug && !options.nodebug)
3815 cdbStructBlock(1,cdbFile);
3817 cleanUpLevel(LabelTab,0);
3818 cleanUpBlock(StructTab,1);
3819 cleanUpBlock(TypedefTab,1);
3821 xstack->syms = NULL;
3822 istack->syms = NULL;