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 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC ( ast * );
56 ast *optimizeGetHbit(ast *);
57 ast *backPatchLabels (ast *,symbol *,symbol *);
61 printTypeChain(tree->ftype,stdout);
66 /*-----------------------------------------------------------------*/
67 /* newAst - creates a fresh node for an expression tree */
68 /*-----------------------------------------------------------------*/
70 ast *newAst (int type, void *op )
73 static int oldLineno = 0 ;
75 Safe_calloc(ex,sizeof(ast));
78 ex->lineno = (noLineno ? oldLineno : yylineno);
79 ex->filename = currFname ;
80 ex->level = NestLevel ;
81 ex->block = currBlockno ;
82 ex->initMode = inInitMode;
84 /* depending on the type */
87 ex->opval.val = (value *) op;
90 ex->opval.op = (long) op ;
93 ex->opval.lnk = (sym_link *) op;
96 ex->opval.stmnt= (unsigned) op;
103 static ast* newAst_(unsigned type)
106 static int oldLineno = 0 ;
108 ex = Safe_calloc(sizeof(ast));
111 ex->lineno = (noLineno ? oldLineno : yylineno);
112 ex->filename = currFname ;
113 ex->level = NestLevel ;
114 ex->block = currBlockno ;
115 ex->initMode = inInitMode;
119 ast* newAst_VALUE(value*val)
121 ast* ex = newAst_(EX_VALUE);
126 ast* newAst_OP(unsigned op)
128 ast*ex = newAst_(EX_OP);
133 ast* newAst_LINK(sym_link*val)
135 ast* ex = newAst_(EX_LINK);
140 ast* newAst_STMNT(unsigned val)
142 ast* ex = newAst_(EX_STMNT);
143 ex->opval.stmnt = val;
147 /*-----------------------------------------------------------------*/
148 /* newNode - creates a new node */
149 /*-----------------------------------------------------------------*/
150 ast *newNode ( long op, ast *left, ast *right )
161 /*-----------------------------------------------------------------*/
162 /* newIfxNode - creates a new Ifx Node */
163 /*-----------------------------------------------------------------*/
164 ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel)
168 /* if this is a literal then we already know the result */
169 if (condAst->etype && IS_LITERAL(condAst->etype)) {
171 /* then depending on the expression value */
172 if ( floatFromVal(condAst->opval.val) )
173 ifxNode = newNode(GOTO,
174 newAst_VALUE(symbolVal(trueLabel)),
177 ifxNode = newNode(GOTO,
178 newAst_VALUE(symbolVal(falseLabel)),
182 ifxNode = newNode(IFX,condAst,NULL);
183 ifxNode->trueLabel = trueLabel;
184 ifxNode->falseLabel= falseLabel;
190 /*-----------------------------------------------------------------*/
191 /* copyAstValues - copies value portion of ast if needed */
192 /*-----------------------------------------------------------------*/
193 void copyAstValues (ast *dest,ast *src)
195 switch (src->opval.op) {
197 dest->values.sym = copySymbolChain(src->values.sym);
201 dest->values.switchVals.swVals =
202 copyValue(src->values.switchVals.swVals);
203 dest->values.switchVals.swDefault =
204 src->values.switchVals.swDefault ;
205 dest->values.switchVals.swNum =
206 src->values.switchVals.swNum ;
210 dest->values.inlineasm = Safe_calloc(strlen(src->values.inlineasm)+1);
211 strcpy(dest->values.inlineasm,src->values.inlineasm);
214 AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel));
215 AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel));
216 AST_FOR(dest,falseLabel) = copySymbol(AST_FOR(src,falseLabel));
217 AST_FOR(dest,condLabel) = copySymbol(AST_FOR(src,condLabel));
218 AST_FOR(dest,initExpr) = copyAst (AST_FOR(src,initExpr)) ;
219 AST_FOR(dest,condExpr) = copyAst (AST_FOR(src,condExpr)) ;
220 AST_FOR(dest,loopExpr) = copyAst (AST_FOR(src,loopExpr)) ;
225 /*-----------------------------------------------------------------*/
226 /* copyAst - makes a copy of a given astession */
227 /*-----------------------------------------------------------------*/
228 ast *copyAst (ast *src)
232 if (!src) return NULL ;
234 dest = Safe_calloc(sizeof(ast));
236 dest->type = src->type ;
237 dest->lineno = src->lineno ;
238 dest->level = src->level ;
239 dest->funcName = src->funcName;
240 dest->argSym = src->argSym;
242 /* if this is a leaf */
244 if (src->type == EX_VALUE) {
245 dest->opval.val = copyValue(src->opval.val);
250 if (src->type == EX_LINK) {
251 dest->opval.lnk = copyLinkChain(src->opval.lnk);
255 dest->opval.op = src->opval.op ;
257 /* if this is a node that has special values */
258 copyAstValues (dest,src);
261 dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ;
263 dest->trueLabel = copySymbol (src->trueLabel);
264 dest->falseLabel= copySymbol (src->falseLabel);
265 dest->left = copyAst(src->left);
266 dest->right= copyAst(src->right);
272 /*-----------------------------------------------------------------*/
273 /* hasSEFcalls - returns TRUE if tree has a function call */
274 /*-----------------------------------------------------------------*/
275 bool hasSEFcalls ( ast *tree)
280 if (tree->type == EX_OP &&
281 ( tree->opval.op == CALL ||
282 tree->opval.op == PCALL ||
283 tree->opval.op == '=' ||
284 tree->opval.op == INC_OP ||
285 tree->opval.op == DEC_OP ))
288 return ( hasSEFcalls(tree->left) |
289 hasSEFcalls(tree->right));
292 /*-----------------------------------------------------------------*/
293 /* isAstEqual - compares two asts & returns 1 if they are equal */
294 /*-----------------------------------------------------------------*/
295 int isAstEqual (ast *t1, ast *t2)
304 if (t1->type != t2->type)
309 if (t1->opval.op != t2->opval.op)
311 return ( isAstEqual(t1->left,t2->left) &&
312 isAstEqual(t1->right,t2->right));
316 if (t1->opval.val->sym) {
317 if (!t2->opval.val->sym)
320 return isSymbolEqual(t1->opval.val->sym,
324 if (t2->opval.val->sym)
327 return (floatFromVal(t1->opval.val) ==
328 floatFromVal(t2->opval.val));
332 /* only compare these two types */
340 /*-----------------------------------------------------------------*/
341 /* resolveSymbols - resolve symbols from the symbol table */
342 /*-----------------------------------------------------------------*/
343 ast *resolveSymbols (ast *tree)
345 /* walk the entire tree and check for values */
346 /* with symbols if we find one then replace */
347 /* symbol with that from the symbol table */
353 /* if not block & function */
354 if ( tree->type == EX_OP &&
355 ( tree->opval.op != FUNCTION &&
356 tree->opval.op != BLOCK &&
357 tree->opval.op != NULLOP )) {
358 filename = tree->filename ;
359 lineno = tree->lineno ;
362 /* make sure we resolve the true & false labels for ifx */
363 if (tree->type == EX_OP && tree->opval.op == IFX ) {
366 if (tree->trueLabel) {
367 if (( csym = findSym(LabelTab,tree->trueLabel,
368 tree->trueLabel->name)))
369 tree->trueLabel = csym ;
371 werror(E_LABEL_UNDEF,tree->trueLabel->name);
374 if (tree->falseLabel) {
375 if (( csym = findSym(LabelTab,
377 tree->falseLabel->name)))
378 tree->falseLabel = csym ;
380 werror(E_LABEL_UNDEF,tree->falseLabel->name);
385 /* if this is a label resolve it from the labelTab*/
386 if (IS_AST_VALUE(tree) &&
387 tree->opval.val->sym &&
388 tree->opval.val->sym->islbl) {
390 symbol *csym = findSym (LabelTab, tree->opval.val->sym ,
391 tree->opval.val->sym->name);
394 werror (E_LABEL_UNDEF,tree->opval.val->sym->name);
396 tree->opval.val->sym = csym ;
398 goto resolveChildren ;
401 /* do only for leafs */
402 if (IS_AST_VALUE(tree) &&
403 tree->opval.val->sym &&
404 ! tree->opval.val->sym->implicit ) {
406 symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym);
408 /* if found in the symbol table & they r not the same */
409 if (csym && tree->opval.val->sym != csym ) {
410 tree->opval.val->sym = csym ;
411 tree->opval.val->type = csym->type;
412 tree->opval.val->etype = csym->etype;
415 /* if not found in the symbol table */
416 /* mark it as undefined assume it is*/
417 /* an integer in data space */
418 if (!csym && !tree->opval.val->sym->implicit) {
420 /* if this is a function name then */
421 /* mark it as returning an int */
422 if (tree->funcName) {
423 tree->opval.val->sym->type = newLink();
424 DCL_TYPE(tree->opval.val->sym->type) = FUNCTION;
425 tree->opval.val->sym->type->next =
426 tree->opval.val->sym->etype = newIntLink();
427 tree->opval.val->etype = tree->opval.val->etype;
428 tree->opval.val->type = tree->opval.val->sym->type;
429 werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name);
431 tree->opval.val->sym->undefined =1 ;
432 tree->opval.val->type =
433 tree->opval.val->etype = newIntLink();
434 tree->opval.val->sym->type =
435 tree->opval.val->sym->etype = newIntLink();
441 resolveSymbols (tree->left);
442 resolveSymbols (tree->right);
447 /*-----------------------------------------------------------------*/
448 /* setAstLineno - walks a ast tree & sets the line number */
449 /*-----------------------------------------------------------------*/
450 int setAstLineno ( ast *tree, int lineno)
455 tree->lineno = lineno ;
456 setAstLineno ( tree->left, lineno);
457 setAstLineno ( tree->right, lineno);
462 /* this functions seems to be superfluous?! kmh */
464 /*-----------------------------------------------------------------*/
465 /* resolveFromTable - will return the symbal table value */
466 /*-----------------------------------------------------------------*/
467 value *resolveFromTable (value *val)
474 csym = findSymWithLevel (SymbolTab,val->sym);
476 /* if found in the symbol table & they r not the same */
477 if (csym && val->sym != csym &&
478 csym->level == val->sym->level &&
483 val->type = csym->type;
484 val->etype = csym->etype;
491 /*-----------------------------------------------------------------*/
492 /* funcOfType :- function of type with name */
493 /*-----------------------------------------------------------------*/
494 symbol *funcOfType (char *name, sym_link *type, sym_link *argType,
495 int nArgs , int rent)
499 /* create the symbol */
500 sym = newSymbol (name,0);
502 /* if arguments required */
506 args = sym->args = newValue();
509 argStack += getSize(type);
510 args->type = copyLinkChain(argType);
511 args->etype = getSpec(args->type);
514 args = args->next = newValue();
518 /* setup return value */
519 sym->type = newLink();
520 DCL_TYPE(sym->type) = FUNCTION;
521 sym->type->next = copyLinkChain(type);
522 sym->etype = getSpec(sym->type);
523 SPEC_RENT(sym->etype) = rent;
528 sym->argStack = (rent ? argStack : 0);
529 allocVariables (sym);
534 /*-----------------------------------------------------------------*/
535 /* reverseParms - will reverse a parameter tree */
536 /*-----------------------------------------------------------------*/
537 void reverseParms (ast *ptree)
543 /* top down if we find a nonParm tree then quit */
544 if (ptree->type == EX_OP && ptree->opval.op == PARAM ) {
546 ptree->left = ptree->right;
547 ptree->right = ttree;
548 reverseParms(ptree->left);
549 reverseParms(ptree->right);
555 /*-----------------------------------------------------------------*/
556 /* processParms - makes sure the parameters are okay and do some */
557 /* processing with them */
558 /*-----------------------------------------------------------------*/
559 int processParms (ast *func, value *defParm,
563 sym_link *fetype = func->etype;
565 /* if none of them exist */
566 if ( !defParm && !actParm)
569 /* if the function is being called via a pointer & */
570 /* it has not been defined a reentrant then we cannot*/
571 /* have parameters */
572 if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) {
573 werror (E_NONRENT_ARGS);
577 /* if defined parameters ended but actual parameters */
578 /* exist and this is not defined as a variable arg */
579 /* also check if statckAuto option is specified */
580 if ((! defParm) && actParm && (!func->hasVargs ) &&
581 !options.stackAuto && !IS_RENT(fetype)) {
582 werror(E_TOO_MANY_PARMS);
586 /* if defined parameters present and actual paramters ended */
587 if ( defParm && ! actParm) {
588 werror(E_TO_FEW_PARMS);
592 /* If this is a varagrs function... */
593 if (!defParm && actParm && func->hasVargs )
597 if (IS_CAST_OP(actParm)
598 || (IS_AST_LIT_VALUE(actParm) && actParm->values.literalFromCast))
600 /* Parameter was explicitly typecast; don't touch it. */
604 /* If it's a small integer, upcast to int. */
605 if (IS_INTEGRAL(actParm->ftype)
606 && getSize(actParm->ftype) < INTSIZE)
608 newType = newAst_LINK(INTTYPE);
611 if (IS_PTR(actParm->ftype) && !IS_GENPTR(actParm->ftype))
613 newType = newAst_LINK(copyLinkChain(actParm->ftype));
614 DCL_TYPE(newType->opval.lnk) = GPOINTER;
617 if (IS_AGGREGATE(actParm->ftype))
619 newType = newAst_LINK(copyLinkChain(actParm->ftype));
620 DCL_TYPE(newType->opval.lnk) = GPOINTER;
625 /* cast required; change this op to a cast. */
626 ast *parmCopy = resolveSymbols(copyAst(actParm));
628 actParm->type = EX_OP;
629 actParm->opval.op = CAST;
630 actParm->left = newType;
631 actParm->right= parmCopy;
632 decorateType(actParm);
634 else if ( actParm->type == EX_OP && actParm->opval.op == PARAM)
636 return (processParms (func,NULL,actParm->left,parmNumber) ||
637 processParms (func,NULL,actParm->right,parmNumber) );
642 /* if defined parameters ended but actual has not & */
644 if (! defParm && actParm &&
645 (options.stackAuto || IS_RENT(fetype)))
648 resolveSymbols(actParm);
649 /* if this is a PARAM node then match left & right */
650 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
652 return (processParms (func,defParm,actParm->left,parmNumber) ||
653 processParms (func,defParm->next, actParm->right,parmNumber) );
656 /* the parameter type must be atleast castable */
657 if (checkType(defParm->type,actParm->ftype) == 0) {
658 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
659 werror(E_CONTINUE,"defined type ");
660 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
661 werror(E_CONTINUE,"actual type ");
662 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
665 /* if the parameter is castable then add the cast */
666 if ( checkType (defParm->type,actParm->ftype) < 0) {
667 ast *pTree = resolveSymbols(copyAst(actParm));
669 /* now change the current one to a cast */
670 actParm->type = EX_OP ;
671 actParm->opval.op = CAST ;
672 actParm->left = newAst_LINK(defParm->type);
673 actParm->right= pTree ;
674 actParm->etype= defParm->etype;
675 actParm->ftype= defParm->type;
678 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
680 actParm->argSym = defParm->sym;
681 /* make a copy and change the regparm type to the defined parm */
682 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
683 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
687 /*-----------------------------------------------------------------*/
688 /* createIvalType - generates ival for basic types */
689 /*-----------------------------------------------------------------*/
690 ast *createIvalType ( ast *sym,sym_link *type, initList *ilist)
694 /* if initList is deep */
695 if ( ilist->type == INIT_DEEP )
696 ilist = ilist->init.deep ;
698 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
699 return decorateType(newNode('=',sym,iExpr));
702 /*-----------------------------------------------------------------*/
703 /* createIvalStruct - generates initial value for structures */
704 /*-----------------------------------------------------------------*/
705 ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
711 sflds = SPEC_STRUCT(type)->fields ;
712 if (ilist->type != INIT_DEEP) {
713 werror(E_INIT_STRUCT,"");
717 iloop = ilist->init.deep;
719 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
722 /* if we have come to end */
726 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
727 lAst = decorateType(resolveSymbols(lAst));
728 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
734 /*-----------------------------------------------------------------*/
735 /* createIvalArray - generates code for array initialization */
736 /*-----------------------------------------------------------------*/
737 ast *createIvalArray (ast *sym, sym_link *type, initList *ilist)
741 int lcnt = 0, size =0 ;
743 /* take care of the special case */
744 /* array of characters can be init */
746 if ( IS_CHAR(type->next) )
747 if ( (rast = createIvalCharPtr(sym,
749 decorateType(resolveSymbols(list2expr(ilist))))))
751 return decorateType(resolveSymbols(rast));
753 /* not the special case */
754 if (ilist->type != INIT_DEEP) {
755 werror(E_INIT_STRUCT,"");
759 iloop = ilist->init.deep ;
760 lcnt = DCL_ELEM(type);
766 aSym = newNode('[',sym,newAst_VALUE(valueFromLit(size-1)));
767 aSym = decorateType(resolveSymbols(aSym));
768 rast = createIval (aSym,type->next,iloop,rast) ;
769 iloop = (iloop ? iloop->next : NULL) ;
772 /* if not array limits given & we */
773 /* are out of initialisers then */
774 if (!DCL_ELEM(type) && !iloop)
777 /* no of elements given and we */
778 /* have generated for all of them */
783 /* if we have not been given a size */
785 DCL_ELEM(type) = size;
787 return decorateType(resolveSymbols(rast));
791 /*-----------------------------------------------------------------*/
792 /* createIvalCharPtr - generates initial values for char pointers */
793 /*-----------------------------------------------------------------*/
794 ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
798 /* if this is a pointer & right is a literal array then */
799 /* just assignment will do */
800 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
801 SPEC_SCLS(iexpr->etype) == S_CODE )
802 && IS_ARRAY(iexpr->ftype)))
803 return newNode('=',sym,iexpr);
805 /* left side is an array so we have to assign each */
807 if (( IS_LITERAL(iexpr->etype) ||
808 SPEC_SCLS(iexpr->etype) == S_CODE )
809 && IS_ARRAY(iexpr->ftype)) {
811 /* for each character generate an assignment */
812 /* to the array element */
813 char *s = SPEC_CVAL(iexpr->etype).v_char ;
817 rast = newNode(NULLOP,
821 newAst_VALUE(valueFromLit(i))),
822 newAst_VALUE(valueFromLit(*s))));
826 rast = newNode(NULLOP,
830 newAst_VALUE(valueFromLit(i))),
831 newAst_VALUE(valueFromLit(*s))));
832 return decorateType(resolveSymbols(rast));
838 /*-----------------------------------------------------------------*/
839 /* createIvalPtr - generates initial value for pointers */
840 /*-----------------------------------------------------------------*/
841 ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
847 if ( ilist->type == INIT_DEEP )
848 ilist = ilist->init.deep ;
850 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
852 /* if character pointer */
853 if (IS_CHAR(type->next))
854 if ((rast = createIvalCharPtr (sym,type,iexpr)))
857 return newNode('=',sym,iexpr);
860 /*-----------------------------------------------------------------*/
861 /* createIval - generates code for initial value */
862 /*-----------------------------------------------------------------*/
863 ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid)
870 /* if structure then */
872 rast = createIvalStruct(sym, type,ilist);
874 /* if this is a pointer */
876 rast = createIvalPtr(sym, type,ilist);
878 /* if this is an array */
880 rast = createIvalArray(sym, type,ilist);
882 /* if type is SPECIFIER */
884 rast = createIvalType (sym,type,ilist);
886 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
888 return decorateType(resolveSymbols(rast)) ;
891 /*-----------------------------------------------------------------*/
892 /* initAggregates - initialises aggregate variables with initv */
893 /*-----------------------------------------------------------------*/
894 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
896 return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
899 /*-----------------------------------------------------------------*/
900 /* gatherAutoInit - creates assignment expressions for initial */
902 /*-----------------------------------------------------------------*/
903 ast *gatherAutoInit ( symbol *autoChain )
910 for ( sym = autoChain ; sym ; sym = sym->next ) {
912 /* resolve the symbols in the ival */
914 resolveIvalSym(sym->ival);
916 /* if this is a static variable & has an */
917 /* initial value the code needs to be lifted */
918 /* here to the main portion since they can be */
919 /* initialised only once at the start */
920 if ( IS_STATIC(sym->etype) && sym->ival &&
921 SPEC_SCLS(sym->etype) != S_CODE) {
924 /* insert the symbol into the symbol table */
925 /* with level = 0 & name = rname */
926 newSym = copySymbol (sym);
927 addSym (SymbolTab,newSym,newSym->name,0,0);
929 /* now lift the code to main */
930 if (IS_AGGREGATE(sym->type))
931 work = initAggregates (sym, sym->ival,NULL);
933 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
934 list2expr(sym->ival));
936 setAstLineno(work,sym->lineDef);
940 staticAutos = newNode(NULLOP,staticAutos,work);
947 /* if there is an initial value */
948 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
949 if (IS_AGGREGATE(sym->type))
950 work = initAggregates (sym,sym->ival,NULL);
952 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
953 list2expr(sym->ival));
955 setAstLineno (work,sym->lineDef);
958 init = newNode(NULLOP,init,work);
967 /*-----------------------------------------------------------------*/
968 /* stringToSymbol - creates a symbol from a literal string */
969 /*-----------------------------------------------------------------*/
970 static value *stringToSymbol (value *val)
972 char name[SDCC_NAME_MAX+1];
973 static int charLbl = 0;
976 sprintf(name,"_str_%d",charLbl++);
977 sym = newSymbol(name,0); /* make it @ level 0 */
978 strcpy(sym->rname,name);
980 /* copy the type from the value passed */
981 sym->type = copyLinkChain(val->type);
982 sym->etype = getSpec(sym->type);
983 /* change to storage class & output class */
984 SPEC_SCLS(sym->etype) = S_CODE ;
985 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
986 SPEC_STAT(sym->etype) = 1;
987 /* make the level & block = 0 */
988 sym->block = sym->level = 0;
991 sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
998 return symbolVal(sym);
1002 /*-----------------------------------------------------------------*/
1003 /* processBlockVars - will go thru the ast looking for block if */
1004 /* a block is found then will allocate the syms */
1005 /* will also gather the auto inits present */
1006 /*-----------------------------------------------------------------*/
1007 ast *processBlockVars ( ast *tree , int *stack, int action)
1012 /* if this is a block */
1013 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
1016 if (action == ALLOCATE) {
1017 autoInit = gatherAutoInit (tree->values.sym);
1018 *stack += allocVariables (tree->values.sym);
1020 /* if there are auto inits then do them */
1022 tree->left = newNode(NULLOP,autoInit,tree->left);
1023 } else /* action is deallocate */
1024 deallocLocal (tree->values.sym) ;
1027 processBlockVars (tree->left, stack, action);
1028 processBlockVars (tree->right, stack, action);
1032 /*-----------------------------------------------------------------*/
1033 /* constExprValue - returns the value of a constant expression */
1034 /*-----------------------------------------------------------------*/
1035 value *constExprValue (ast *cexpr, int check)
1037 cexpr = decorateType(resolveSymbols(cexpr));
1039 /* if this is not a constant then */
1040 if (!IS_LITERAL(cexpr->ftype)) {
1041 /* then check if this is a literal array
1043 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
1044 SPEC_CVAL(cexpr->etype).v_char &&
1045 IS_ARRAY(cexpr->ftype)) {
1046 value *val = valFromType(cexpr->ftype);
1047 SPEC_SCLS(val->etype) = S_LITERAL;
1048 val->sym =cexpr->opval.val->sym ;
1049 val->sym->type = copyLinkChain(cexpr->ftype);
1050 val->sym->etype = getSpec(val->sym->type);
1051 strcpy(val->name,cexpr->opval.val->sym->rname);
1055 /* if we are casting a literal value then */
1056 if (IS_AST_OP(cexpr) &&
1057 cexpr->opval.op == CAST &&
1058 IS_LITERAL(cexpr->left->ftype))
1059 return valCastLiteral(cexpr->ftype,
1060 floatFromVal(cexpr->left->opval.val));
1062 if (IS_AST_VALUE(cexpr))
1063 return cexpr->opval.val;
1066 werror(E_CONST_EXPECTED,"found expression");
1071 /* return the value */
1072 return cexpr->opval.val ;
1076 /*-----------------------------------------------------------------*/
1077 /* isLabelInAst - will return true if a given label is found */
1078 /*-----------------------------------------------------------------*/
1079 bool isLabelInAst (symbol *label, ast *tree)
1081 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1084 if (IS_AST_OP(tree) &&
1085 tree->opval.op == LABEL &&
1086 isSymbolEqual(AST_SYMBOL(tree->left),label))
1089 return isLabelInAst(label,tree->right) &&
1090 isLabelInAst(label,tree->left);
1094 /*-----------------------------------------------------------------*/
1095 /* isLoopCountable - return true if the loop count can be determi- */
1096 /* -ned at compile time . */
1097 /*-----------------------------------------------------------------*/
1098 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1099 symbol **sym,ast **init, ast **end)
1102 /* the loop is considered countable if the following
1103 conditions are true :-
1105 a) initExpr :- <sym> = <const>
1106 b) condExpr :- <sym> < <const1>
1107 c) loopExpr :- <sym> ++
1110 /* first check the initExpr */
1111 if ( IS_AST_OP(initExpr) &&
1112 initExpr->opval.op == '=' && /* is assignment */
1113 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1115 *sym = AST_SYMBOL(initExpr->left);
1116 *init= initExpr->right;
1121 /* for now the symbol has to be of
1123 if (!IS_INTEGRAL((*sym)->type))
1126 /* now check condExpr */
1127 if (IS_AST_OP(condExpr)) {
1129 switch (condExpr->opval.op) {
1131 if (IS_AST_SYM_VALUE(condExpr->left) &&
1132 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1133 IS_AST_LIT_VALUE(condExpr->right)) {
1134 *end = condExpr->right;
1140 if (IS_AST_OP(condExpr->left) &&
1141 condExpr->left->opval.op == '>' &&
1142 IS_AST_LIT_VALUE(condExpr->left->right) &&
1143 IS_AST_SYM_VALUE(condExpr->left->left)&&
1144 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1146 *end = newNode('+', condExpr->left->right,
1147 newAst_VALUE(constVal("1")));
1158 /* check loop expression is of the form <sym>++ */
1159 if (!IS_AST_OP(loopExpr))
1162 /* check if <sym> ++ */
1163 if (loopExpr->opval.op == INC_OP) {
1165 if (loopExpr->left) {
1167 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1168 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1173 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1174 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1181 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1183 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1184 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1185 IS_AST_LIT_VALUE(loopExpr->right) &&
1186 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1194 /*-----------------------------------------------------------------*/
1195 /* astHasVolatile - returns true if ast contains any volatile */
1196 /*-----------------------------------------------------------------*/
1197 bool astHasVolatile (ast *tree)
1202 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1205 if (IS_AST_OP(tree))
1206 return astHasVolatile(tree->left) ||
1207 astHasVolatile(tree->right);
1212 /*-----------------------------------------------------------------*/
1213 /* astHasPointer - return true if the ast contains any ptr variable*/
1214 /*-----------------------------------------------------------------*/
1215 bool astHasPointer (ast *tree)
1220 if (IS_AST_LINK(tree))
1223 /* if we hit an array expression then check
1224 only the left side */
1225 if (IS_AST_OP(tree) && tree->opval.op == '[')
1226 return astHasPointer(tree->left);
1228 if (IS_AST_VALUE(tree))
1229 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1231 return astHasPointer(tree->left) ||
1232 astHasPointer(tree->right);
1236 /*-----------------------------------------------------------------*/
1237 /* astHasSymbol - return true if the ast has the given symbol */
1238 /*-----------------------------------------------------------------*/
1239 bool astHasSymbol (ast *tree, symbol *sym)
1241 if (!tree || IS_AST_LINK(tree))
1244 if (IS_AST_VALUE(tree)) {
1245 if (IS_AST_SYM_VALUE(tree))
1246 return isSymbolEqual(AST_SYMBOL(tree),sym);
1251 return astHasSymbol(tree->left,sym) ||
1252 astHasSymbol(tree->right,sym);
1255 /*-----------------------------------------------------------------*/
1256 /* isConformingBody - the loop body has to conform to a set of rules */
1257 /* for the loop to be considered reversible read on for rules */
1258 /*-----------------------------------------------------------------*/
1259 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1262 /* we are going to do a pre-order traversal of the
1263 tree && check for the following conditions. (essentially
1264 a set of very shallow tests )
1265 a) the sym passed does not participate in
1266 any arithmetic operation
1267 b) There are no function calls
1268 c) all jumps are within the body
1269 d) address of loop control variable not taken
1270 e) if an assignment has a pointer on the
1271 left hand side make sure right does not have
1272 loop control variable */
1274 /* if we reach the end or a leaf then true */
1275 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1279 /* if anything else is "volatile" */
1280 if (IS_VOLATILE(TETYPE(pbody)))
1283 /* we will walk the body in a pre-order traversal for
1285 switch (pbody->opval.op) {
1286 /*------------------------------------------------------------------*/
1288 return isConformingBody (pbody->right,sym,body);
1290 /*------------------------------------------------------------------*/
1295 /*------------------------------------------------------------------*/
1296 case INC_OP: /* incerement operator unary so left only */
1299 /* sure we are not sym is not modified */
1301 IS_AST_SYM_VALUE(pbody->left) &&
1302 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1306 IS_AST_SYM_VALUE(pbody->right) &&
1307 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1312 /*------------------------------------------------------------------*/
1314 case '*' : /* can be unary : if right is null then unary operation */
1319 /* if right is NULL then unary operation */
1320 /*------------------------------------------------------------------*/
1321 /*----------------------------*/
1323 /*----------------------------*/
1324 if ( ! pbody->right ) {
1325 if (IS_AST_SYM_VALUE(pbody->left) &&
1326 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1329 return isConformingBody(pbody->left,sym,body) ;
1331 if (astHasSymbol(pbody->left,sym) ||
1332 astHasSymbol(pbody->right,sym))
1337 /*------------------------------------------------------------------*/
1345 if (IS_AST_SYM_VALUE(pbody->left) &&
1346 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1349 if (IS_AST_SYM_VALUE(pbody->right) &&
1350 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1353 return isConformingBody(pbody->left,sym,body) &&
1354 isConformingBody(pbody->right,sym,body);
1361 if (IS_AST_SYM_VALUE(pbody->left) &&
1362 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1364 return isConformingBody (pbody->left,sym,body);
1366 /*------------------------------------------------------------------*/
1378 case SIZEOF: /* evaluate wihout code generation */
1380 return isConformingBody(pbody->left,sym,body) &&
1381 isConformingBody(pbody->right,sym,body);
1383 /*------------------------------------------------------------------*/
1386 /* if left has a pointer & right has loop
1387 control variable then we cannot */
1388 if (astHasPointer(pbody->left) &&
1389 astHasSymbol (pbody->right,sym))
1391 if (astHasVolatile(pbody->left))
1394 if (IS_AST_SYM_VALUE(pbody->left) &&
1395 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1398 if (astHasVolatile(pbody->left))
1401 return isConformingBody(pbody->left,sym,body) &&
1402 isConformingBody(pbody->right,sym,body);
1413 assert("Parser should not have generated this\n");
1415 /*------------------------------------------------------------------*/
1416 /*----------------------------*/
1417 /* comma operator */
1418 /*----------------------------*/
1420 return isConformingBody(pbody->left,sym,body) &&
1421 isConformingBody(pbody->right,sym,body);
1423 /*------------------------------------------------------------------*/
1424 /*----------------------------*/
1426 /*----------------------------*/
1430 /*------------------------------------------------------------------*/
1431 /*----------------------------*/
1432 /* return statement */
1433 /*----------------------------*/
1438 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1443 if (astHasSymbol(pbody->left,sym))
1450 return isConformingBody(pbody->left,sym,body) &&
1451 isConformingBody(pbody->right,sym,body);
1457 /*-----------------------------------------------------------------*/
1458 /* isLoopReversible - takes a for loop as input && returns true */
1459 /* if the for loop is reversible. If yes will set the value of */
1460 /* the loop control var & init value & termination value */
1461 /*-----------------------------------------------------------------*/
1462 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1463 ast **init, ast **end )
1465 /* if option says don't do it then don't */
1466 if (optimize.noLoopReverse)
1468 /* there are several tests to determine this */
1470 /* for loop has to be of the form
1471 for ( <sym> = <const1> ;
1472 [<sym> < <const2>] ;
1473 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1475 if (! isLoopCountable (AST_FOR(loop,initExpr),
1476 AST_FOR(loop,condExpr),
1477 AST_FOR(loop,loopExpr),
1478 loopCntrl,init,end))
1481 /* now do some serious checking on the body of the loop
1484 return isConformingBody(loop->left,*loopCntrl,loop->left);
1488 /*-----------------------------------------------------------------*/
1489 /* replLoopSym - replace the loop sym by loop sym -1 */
1490 /*-----------------------------------------------------------------*/
1491 static void replLoopSym ( ast *body, symbol *sym)
1494 if (!body || IS_AST_LINK(body))
1497 if (IS_AST_SYM_VALUE(body)) {
1499 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1502 body->opval.op = '-';
1503 body->left = newAst_VALUE(symbolVal(sym));
1504 body->right= newAst_VALUE(constVal("1"));
1512 replLoopSym(body->left,sym);
1513 replLoopSym(body->right,sym);
1517 /*-----------------------------------------------------------------*/
1518 /* reverseLoop - do the actual loop reversal */
1519 /*-----------------------------------------------------------------*/
1520 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1524 /* create the following tree
1529 if (sym) goto for_continue ;
1532 /* put it together piece by piece */
1533 rloop = newNode (NULLOP,
1534 createIf(newAst_VALUE(symbolVal(sym)),
1536 newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1539 newAst_VALUE(symbolVal(sym)),
1542 replLoopSym(loop->left, sym);
1544 rloop = newNode(NULLOP,
1546 newAst_VALUE(symbolVal(sym)),
1547 newNode('-',end,init)),
1548 createLabel(AST_FOR(loop,continueLabel),
1553 newAst_VALUE(symbolVal(sym)),
1554 newAst_VALUE(constVal("1"))),
1557 return decorateType(rloop);
1561 #define DEMAND_INTEGER_PROMOTION
1563 #ifdef DEMAND_INTEGER_PROMOTION
1565 /*-----------------------------------------------------------------*/
1566 /* walk a tree looking for the leaves. Add a typecast to the given */
1567 /* type to each value leaf node. */
1568 /*-----------------------------------------------------------------*/
1569 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1573 /* WTF? We should never get here. */
1577 if (!node->left && !node->right)
1579 /* We're at a leaf; if it's a value, apply the typecast */
1580 if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1582 *parentPtr = decorateType(newNode(CAST,
1583 newAst_LINK(copyLinkChain(type)),
1591 pushTypeCastToLeaves(type, node->left, &(node->left));
1595 pushTypeCastToLeaves(type, node->right, &(node->right));
1602 /*-----------------------------------------------------------------*/
1603 /* Given an assignment operation in a tree, determine if the LHS */
1604 /* (the result) has a different (integer) type than the RHS. */
1605 /* If so, walk the RHS and add a typecast to the type of the LHS */
1606 /* to all leaf nodes. */
1607 /*-----------------------------------------------------------------*/
1608 void propAsgType(ast *tree)
1610 #ifdef DEMAND_INTEGER_PROMOTION
1611 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1613 /* Nothing to do here... */
1617 if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
1619 pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1626 /*-----------------------------------------------------------------*/
1627 /* decorateType - compute type for this tree also does type cheking*/
1628 /* this is done bottom up, since type have to flow upwards*/
1629 /* it also does constant folding, and paramater checking */
1630 /*-----------------------------------------------------------------*/
1631 ast *decorateType (ast *tree)
1639 /* if already has type then do nothing */
1640 if ( tree->decorated )
1643 tree->decorated = 1;
1645 /* print the line */
1646 /* if not block & function */
1647 if ( tree->type == EX_OP &&
1648 ( tree->opval.op != FUNCTION &&
1649 tree->opval.op != BLOCK &&
1650 tree->opval.op != NULLOP )) {
1651 filename = tree->filename ;
1652 lineno = tree->lineno ;
1655 /* if any child is an error | this one is an error do nothing */
1656 if ( tree->isError ||
1657 ( tree->left && tree->left->isError) ||
1658 ( tree->right && tree->right->isError ))
1661 /*------------------------------------------------------------------*/
1662 /*----------------------------*/
1663 /* leaf has been reached */
1664 /*----------------------------*/
1665 /* if this is of type value */
1666 /* just get the type */
1667 if ( tree->type == EX_VALUE ) {
1669 if ( IS_LITERAL(tree->opval.val->etype) ) {
1671 /* if this is a character array then declare it */
1672 if (IS_ARRAY(tree->opval.val->type))
1673 tree->opval.val = stringToSymbol(tree->opval.val);
1675 /* otherwise just copy the type information */
1676 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1677 if (funcInChain(tree->opval.val->type)) {
1678 tree->hasVargs = tree->opval.val->sym->hasVargs;
1679 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1684 if ( tree->opval.val->sym ) {
1685 /* if the undefined flag is set then give error message */
1686 if (tree->opval.val->sym->undefined ) {
1687 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1689 TTYPE(tree) = TETYPE(tree) =
1690 tree->opval.val->type = tree->opval.val->sym->type =
1691 tree->opval.val->etype = tree->opval.val->sym->etype =
1692 copyLinkChain(INTTYPE);
1696 /* if impilicit i.e. struct/union member then no type */
1697 if (tree->opval.val->sym->implicit )
1698 TTYPE(tree) = TETYPE(tree) = NULL ;
1702 /* else copy the type */
1703 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1705 /* and mark it as referenced */
1706 tree->opval.val->sym->isref = 1;
1707 /* if this is of type function or function pointer */
1708 if (funcInChain(tree->opval.val->type)) {
1709 tree->hasVargs = tree->opval.val->sym->hasVargs;
1710 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1720 /* if type link for the case of cast */
1721 if ( tree->type == EX_LINK ) {
1722 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1729 dtl = decorateType (tree->left);
1730 dtr = decorateType (tree->right);
1732 /* this is to take care of situations
1733 when the tree gets rewritten */
1734 if (dtl != tree->left)
1736 if (dtr != tree->right)
1740 /* depending on type of operator do */
1742 switch (tree->opval.op) {
1743 /*------------------------------------------------------------------*/
1744 /*----------------------------*/
1746 /*----------------------------*/
1749 /* determine which is the array & which the index */
1750 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1752 ast *tempTree = tree->left ;
1753 tree->left = tree->right ;
1754 tree->right= tempTree ;
1757 /* first check if this is a array or a pointer */
1758 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1759 werror(E_NEED_ARRAY_PTR,"[]");
1760 goto errorTreeReturn ;
1763 /* check if the type of the idx */
1764 if (!IS_INTEGRAL(RTYPE(tree))) {
1765 werror(E_IDX_NOT_INT);
1766 goto errorTreeReturn ;
1769 /* if the left is an rvalue then error */
1771 werror(E_LVALUE_REQUIRED,"array access");
1772 goto errorTreeReturn ;
1775 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1778 /*------------------------------------------------------------------*/
1779 /*----------------------------*/
1781 /*----------------------------*/
1783 /* if this is not a structure */
1784 if (!IS_STRUCT(LTYPE(tree))) {
1785 werror(E_STRUCT_UNION,".");
1786 goto errorTreeReturn ;
1788 TTYPE(tree) = structElemType (LTYPE(tree),
1789 (tree->right->type == EX_VALUE ?
1790 tree->right->opval.val : NULL ),&tree->args);
1791 TETYPE(tree) = getSpec(TTYPE(tree));
1794 /*------------------------------------------------------------------*/
1795 /*----------------------------*/
1796 /* struct/union pointer */
1797 /*----------------------------*/
1799 /* if not pointer to a structure */
1800 if (!IS_PTR(LTYPE(tree))) {
1802 goto errorTreeReturn ;
1805 if (!IS_STRUCT(LTYPE(tree)->next)) {
1806 werror(E_STRUCT_UNION,"->");
1807 goto errorTreeReturn ;
1810 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1811 (tree->right->type == EX_VALUE ?
1812 tree->right->opval.val : NULL ),&tree->args);
1813 TETYPE(tree) = getSpec(TTYPE(tree));
1816 /*------------------------------------------------------------------*/
1817 /*----------------------------*/
1818 /* ++/-- operation */
1819 /*----------------------------*/
1820 case INC_OP: /* incerement operator unary so left only */
1823 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1824 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1825 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1826 werror(E_CODE_WRITE,"++/--");
1835 /*------------------------------------------------------------------*/
1836 /*----------------------------*/
1838 /*----------------------------*/
1839 case '&': /* can be unary */
1840 /* if right is NULL then unary operation */
1841 if ( tree->right ) /* not an unary operation */ {
1843 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1844 werror(E_BITWISE_OP);
1845 werror(E_CONTINUE,"left & right types are ");
1846 printTypeChain(LTYPE(tree),stderr);
1847 fprintf(stderr,",");
1848 printTypeChain(RTYPE(tree),stderr);
1849 fprintf(stderr,"\n");
1850 goto errorTreeReturn ;
1853 /* if they are both literal */
1854 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1855 tree->type = EX_VALUE ;
1856 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1857 valFromType(RETYPE(tree)),'&');
1859 tree->right = tree->left = NULL;
1860 TETYPE(tree) = tree->opval.val->etype ;
1861 TTYPE(tree) = tree->opval.val->type;
1865 /* see if this is a GETHBIT operation if yes
1868 ast *otree = optimizeGetHbit(tree);
1871 return decorateType(otree);
1874 /* if right or left is literal then result of that type*/
1875 if (IS_LITERAL(RTYPE(tree))) {
1877 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1878 TETYPE(tree) = getSpec(TTYPE(tree));
1879 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1882 if (IS_LITERAL(LTYPE(tree))) {
1883 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1884 TETYPE(tree) = getSpec(TTYPE(tree));
1885 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1890 computeType (LTYPE(tree), RTYPE(tree));
1891 TETYPE(tree) = getSpec(TTYPE(tree));
1894 LRVAL(tree) = RRVAL(tree) = 1;
1898 /*------------------------------------------------------------------*/
1899 /*----------------------------*/
1901 /*----------------------------*/
1903 p->class = DECLARATOR;
1904 /* if bit field then error */
1905 if (IS_BITVAR(tree->left->etype)) {
1906 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1907 goto errorTreeReturn ;
1910 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1911 werror (E_ILLEGAL_ADDR,"address of register variable");
1912 goto errorTreeReturn;
1915 if (IS_FUNC(LTYPE(tree))) {
1916 werror(E_ILLEGAL_ADDR,"address of function");
1917 goto errorTreeReturn ;
1921 werror(E_LVALUE_REQUIRED,"address of");
1922 goto errorTreeReturn ;
1924 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1925 DCL_TYPE(p) = CPOINTER ;
1926 DCL_PTR_CONST(p) = port->mem.code_ro;
1929 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1930 DCL_TYPE(p) = FPOINTER;
1932 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1933 DCL_TYPE(p) = PPOINTER ;
1935 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1936 DCL_TYPE(p) = IPOINTER ;
1938 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1939 DCL_TYPE(p) = EEPPOINTER ;
1941 DCL_TYPE(p) = POINTER ;
1943 if (IS_AST_SYM_VALUE(tree->left)) {
1944 AST_SYMBOL(tree->left)->addrtaken = 1;
1945 AST_SYMBOL(tree->left)->allocreq = 1;
1948 p->next = LTYPE(tree);
1950 TETYPE(tree) = getSpec(TTYPE(tree));
1951 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1952 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1957 /*------------------------------------------------------------------*/
1958 /*----------------------------*/
1960 /*----------------------------*/
1962 /* if the rewrite succeeds then don't go any furthur */
1964 ast *wtree = optimizeRRCRLC ( tree );
1966 return decorateType(wtree) ;
1968 /*------------------------------------------------------------------*/
1969 /*----------------------------*/
1971 /*----------------------------*/
1973 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1974 werror(E_BITWISE_OP);
1975 werror(E_CONTINUE,"left & right types are ");
1976 printTypeChain(LTYPE(tree),stderr);
1977 fprintf(stderr,",");
1978 printTypeChain(RTYPE(tree),stderr);
1979 fprintf(stderr,"\n");
1980 goto errorTreeReturn ;
1983 /* if they are both literal then */
1984 /* rewrite the tree */
1985 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1986 tree->type = EX_VALUE ;
1987 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1988 valFromType(RETYPE(tree)),
1990 tree->right = tree->left = NULL;
1991 TETYPE(tree) = tree->opval.val->etype;
1992 TTYPE(tree) = tree->opval.val->type;
1995 LRVAL(tree) = RRVAL(tree) = 1;
1996 TETYPE(tree) = getSpec (TTYPE(tree) =
1997 computeType(LTYPE(tree),
2000 /*------------------------------------------------------------------*/
2001 /*----------------------------*/
2003 /*----------------------------*/
2005 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2006 werror(E_INVALID_OP,"divide");
2007 goto errorTreeReturn ;
2009 /* if they are both literal then */
2010 /* rewrite the tree */
2011 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2012 tree->type = EX_VALUE ;
2013 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
2014 valFromType(RETYPE(tree)));
2015 tree->right = tree->left = NULL;
2016 TETYPE(tree) = getSpec(TTYPE(tree) =
2017 tree->opval.val->type);
2020 LRVAL(tree) = RRVAL(tree) = 1;
2021 TETYPE(tree) = getSpec (TTYPE(tree) =
2022 computeType(LTYPE(tree),
2026 /*------------------------------------------------------------------*/
2027 /*----------------------------*/
2029 /*----------------------------*/
2031 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
2032 werror(E_BITWISE_OP);
2033 werror(E_CONTINUE,"left & right types are ");
2034 printTypeChain(LTYPE(tree),stderr);
2035 fprintf(stderr,",");
2036 printTypeChain(RTYPE(tree),stderr);
2037 fprintf(stderr,"\n");
2038 goto errorTreeReturn ;
2040 /* if they are both literal then */
2041 /* rewrite the tree */
2042 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2043 tree->type = EX_VALUE ;
2044 tree->opval.val = valMod (valFromType(LETYPE(tree)),
2045 valFromType(RETYPE(tree)));
2046 tree->right = tree->left = NULL;
2047 TETYPE(tree) = getSpec(TTYPE(tree) =
2048 tree->opval.val->type);
2051 LRVAL(tree) = RRVAL(tree) = 1;
2052 TETYPE(tree) = getSpec (TTYPE(tree) =
2053 computeType(LTYPE(tree),
2057 /*------------------------------------------------------------------*/
2058 /*----------------------------*/
2059 /* address dereference */
2060 /*----------------------------*/
2061 case '*': /* can be unary : if right is null then unary operation */
2062 if ( ! tree->right ) {
2063 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2065 goto errorTreeReturn ;
2069 werror(E_LVALUE_REQUIRED,"pointer deref");
2070 goto errorTreeReturn ;
2072 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2073 LTYPE(tree)->next : NULL );
2074 TETYPE(tree) = getSpec(TTYPE(tree));
2075 tree->args = tree->left->args ;
2076 tree->hasVargs = tree->left->hasVargs ;
2077 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2081 /*------------------------------------------------------------------*/
2082 /*----------------------------*/
2083 /* multiplication */
2084 /*----------------------------*/
2085 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2086 werror(E_INVALID_OP,"multiplication");
2087 goto errorTreeReturn ;
2090 /* if they are both literal then */
2091 /* rewrite the tree */
2092 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2093 tree->type = EX_VALUE ;
2094 tree->opval.val = valMult (valFromType(LETYPE(tree)),
2095 valFromType(RETYPE(tree)));
2096 tree->right = tree->left = NULL;
2097 TETYPE(tree) = getSpec(TTYPE(tree) =
2098 tree->opval.val->type);
2102 /* if left is a literal exchange left & right */
2103 if (IS_LITERAL(LTYPE(tree))) {
2104 ast *tTree = tree->left ;
2105 tree->left = tree->right ;
2106 tree->right= tTree ;
2109 LRVAL(tree) = RRVAL(tree) = 1;
2110 TETYPE(tree) = getSpec (TTYPE(tree) =
2111 computeType(LTYPE(tree),
2115 /*------------------------------------------------------------------*/
2116 /*----------------------------*/
2117 /* unary '+' operator */
2118 /*----------------------------*/
2121 if ( ! tree->right ) {
2122 if (!IS_INTEGRAL(LTYPE(tree))) {
2123 werror(E_UNARY_OP,'+');
2124 goto errorTreeReturn ;
2127 /* if left is a literal then do it */
2128 if (IS_LITERAL(LTYPE(tree))) {
2129 tree->type = EX_VALUE ;
2130 tree->opval.val = valFromType(LETYPE(tree));
2132 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2136 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2140 /*------------------------------------------------------------------*/
2141 /*----------------------------*/
2143 /*----------------------------*/
2145 /* this is not a unary operation */
2146 /* if both pointers then problem */
2147 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2148 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2149 werror(E_PTR_PLUS_PTR);
2150 goto errorTreeReturn ;
2153 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2154 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2155 werror(E_PLUS_INVALID,"+");
2156 goto errorTreeReturn ;
2159 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2160 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2161 werror(E_PLUS_INVALID,"+");
2162 goto errorTreeReturn;
2164 /* if they are both literal then */
2165 /* rewrite the tree */
2166 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2167 tree->type = EX_VALUE ;
2168 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2169 valFromType(RETYPE(tree)));
2170 tree->right = tree->left = NULL;
2171 TETYPE(tree) = getSpec(TTYPE(tree) =
2172 tree->opval.val->type);
2176 /* if the right is a pointer or left is a literal
2177 xchange left & right */
2178 if (IS_ARRAY(RTYPE(tree)) ||
2179 IS_PTR(RTYPE(tree)) ||
2180 IS_LITERAL(LTYPE(tree))) {
2181 ast *tTree = tree->left ;
2182 tree->left = tree->right ;
2183 tree->right= tTree ;
2186 LRVAL(tree) = RRVAL(tree) = 1;
2187 /* if the left is a pointer */
2188 if (IS_PTR(LTYPE(tree)))
2189 TETYPE(tree) = getSpec(TTYPE(tree) =
2192 TETYPE(tree) = getSpec(TTYPE(tree) =
2193 computeType(LTYPE(tree),
2197 /*------------------------------------------------------------------*/
2198 /*----------------------------*/
2200 /*----------------------------*/
2201 case '-' : /* can be unary */
2202 /* if right is null then unary */
2203 if ( ! tree->right ) {
2205 if (!IS_ARITHMETIC(LTYPE(tree))) {
2206 werror(E_UNARY_OP,tree->opval.op);
2207 goto errorTreeReturn ;
2210 /* if left is a literal then do it */
2211 if (IS_LITERAL(LTYPE(tree))) {
2212 tree->type = EX_VALUE ;
2213 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2215 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2219 TTYPE(tree) = LTYPE(tree);
2223 /*------------------------------------------------------------------*/
2224 /*----------------------------*/
2226 /*----------------------------*/
2228 if (!(IS_PTR(LTYPE(tree)) ||
2229 IS_ARRAY(LTYPE(tree)) ||
2230 IS_ARITHMETIC(LTYPE(tree)))) {
2231 werror(E_PLUS_INVALID,"-");
2232 goto errorTreeReturn ;
2235 if (!(IS_PTR(RTYPE(tree)) ||
2236 IS_ARRAY(RTYPE(tree)) ||
2237 IS_ARITHMETIC(RTYPE(tree)))) {
2238 werror(E_PLUS_INVALID,"-");
2239 goto errorTreeReturn ;
2242 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2243 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2244 IS_INTEGRAL(RTYPE(tree))) ) {
2245 werror(E_PLUS_INVALID,"-");
2246 goto errorTreeReturn ;
2249 /* if they are both literal then */
2250 /* rewrite the tree */
2251 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2252 tree->type = EX_VALUE ;
2253 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2254 valFromType(RETYPE(tree)));
2255 tree->right = tree->left = NULL;
2256 TETYPE(tree) = getSpec(TTYPE(tree) =
2257 tree->opval.val->type);
2261 /* if the left & right are equal then zero */
2262 if (isAstEqual(tree->left,tree->right)) {
2263 tree->type = EX_VALUE;
2264 tree->left = tree->right = NULL;
2265 tree->opval.val = constVal("0");
2266 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2270 /* if both of them are pointers or arrays then */
2271 /* the result is going to be an integer */
2272 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2273 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2274 TETYPE(tree) = TTYPE(tree) = newIntLink();
2276 /* if only the left is a pointer */
2277 /* then result is a pointer */
2278 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2279 TETYPE(tree) = getSpec(TTYPE(tree) =
2282 TETYPE(tree) = getSpec (TTYPE(tree) =
2283 computeType(LTYPE(tree),
2285 LRVAL(tree) = RRVAL(tree) = 1;
2288 /*------------------------------------------------------------------*/
2289 /*----------------------------*/
2291 /*----------------------------*/
2293 /* can be only integral type */
2294 if (!IS_INTEGRAL(LTYPE(tree))) {
2295 werror(E_UNARY_OP,tree->opval.op);
2296 goto errorTreeReturn ;
2299 /* if left is a literal then do it */
2300 if (IS_LITERAL(LTYPE(tree))) {
2301 tree->type = EX_VALUE ;
2302 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2304 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2308 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2311 /*------------------------------------------------------------------*/
2312 /*----------------------------*/
2314 /*----------------------------*/
2316 /* can be pointer */
2317 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2318 !IS_PTR(LTYPE(tree)) &&
2319 !IS_ARRAY(LTYPE(tree))) {
2320 werror(E_UNARY_OP,tree->opval.op);
2321 goto errorTreeReturn ;
2324 /* if left is a literal then do it */
2325 if (IS_LITERAL(LTYPE(tree))) {
2326 tree->type = EX_VALUE ;
2327 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2329 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2333 TTYPE(tree) = TETYPE(tree) = newCharLink();
2336 /*------------------------------------------------------------------*/
2337 /*----------------------------*/
2339 /*----------------------------*/
2342 TTYPE(tree) = LTYPE(tree);
2343 TETYPE(tree) = LETYPE(tree);
2347 TTYPE(tree) = TETYPE(tree) = newCharLink();
2352 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2353 werror(E_SHIFT_OP_INVALID);
2354 werror(E_CONTINUE,"left & right types are ");
2355 printTypeChain(LTYPE(tree),stderr);
2356 fprintf(stderr,",");
2357 printTypeChain(RTYPE(tree),stderr);
2358 fprintf(stderr,"\n");
2359 goto errorTreeReturn ;
2362 /* if they are both literal then */
2363 /* rewrite the tree */
2364 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2365 tree->type = EX_VALUE ;
2366 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2367 valFromType(RETYPE(tree)),
2368 (tree->opval.op == LEFT_OP ? 1 : 0));
2369 tree->right = tree->left = NULL;
2370 TETYPE(tree) = getSpec(TTYPE(tree) =
2371 tree->opval.val->type);
2374 /* if only the right side is a literal & we are
2375 shifting more than size of the left operand then zero */
2376 if (IS_LITERAL(RTYPE(tree)) &&
2377 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2378 (getSize(LTYPE(tree))*8)) {
2379 werror(W_SHIFT_CHANGED,
2380 (tree->opval.op == LEFT_OP ? "left" : "right"));
2381 tree->type = EX_VALUE;
2382 tree->left = tree->right = NULL;
2383 tree->opval.val = constVal("0");
2384 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2387 LRVAL(tree) = RRVAL(tree) = 1;
2388 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2389 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2391 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2395 /*------------------------------------------------------------------*/
2396 /*----------------------------*/
2398 /*----------------------------*/
2399 case CAST: /* change the type */
2400 /* cannot cast to an aggregate type */
2401 if (IS_AGGREGATE(LTYPE(tree))) {
2402 werror(E_CAST_ILLEGAL);
2403 goto errorTreeReturn ;
2406 /* if the right is a literal replace the tree */
2407 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2408 tree->type = EX_VALUE ;
2410 valCastLiteral(LTYPE(tree),
2411 floatFromVal(valFromType(RETYPE(tree))));
2414 TTYPE(tree) = tree->opval.val->type;
2415 tree->values.literalFromCast = 1;
2418 TTYPE(tree) = LTYPE(tree);
2422 TETYPE(tree) = getSpec(TTYPE(tree));
2426 /*------------------------------------------------------------------*/
2427 /*----------------------------*/
2428 /* logical &&, || */
2429 /*----------------------------*/
2432 /* each must me arithmetic type or be a pointer */
2433 if (!IS_PTR(LTYPE(tree)) &&
2434 !IS_ARRAY(LTYPE(tree)) &&
2435 !IS_INTEGRAL(LTYPE(tree))) {
2436 werror(E_COMPARE_OP);
2437 goto errorTreeReturn ;
2440 if (!IS_PTR(RTYPE(tree)) &&
2441 !IS_ARRAY(RTYPE(tree)) &&
2442 !IS_INTEGRAL(RTYPE(tree))) {
2443 werror(E_COMPARE_OP);
2444 goto errorTreeReturn ;
2446 /* if they are both literal then */
2447 /* rewrite the tree */
2448 if (IS_LITERAL(RTYPE(tree)) &&
2449 IS_LITERAL(LTYPE(tree))) {
2450 tree->type = EX_VALUE ;
2451 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2452 valFromType(RETYPE(tree)),
2454 tree->right = tree->left = NULL;
2455 TETYPE(tree) = getSpec(TTYPE(tree) =
2456 tree->opval.val->type);
2459 LRVAL(tree) = RRVAL(tree) = 1;
2460 TTYPE(tree) = TETYPE(tree) = newCharLink();
2463 /*------------------------------------------------------------------*/
2464 /*----------------------------*/
2465 /* comparison operators */
2466 /*----------------------------*/
2474 ast *lt = optimizeCompare(tree);
2480 /* if they are pointers they must be castable */
2481 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2482 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2483 werror(E_COMPARE_OP);
2484 fprintf(stderr,"comparing type ");
2485 printTypeChain(LTYPE(tree),stderr);
2486 fprintf(stderr,"to type ");
2487 printTypeChain(RTYPE(tree),stderr);
2488 fprintf(stderr,"\n");
2489 goto errorTreeReturn ;
2492 /* else they should be promotable to one another */
2494 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2495 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2497 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2498 werror(E_COMPARE_OP);
2499 fprintf(stderr,"comparing type ");
2500 printTypeChain(LTYPE(tree),stderr);
2501 fprintf(stderr,"to type ");
2502 printTypeChain(RTYPE(tree),stderr);
2503 fprintf(stderr,"\n");
2504 goto errorTreeReturn ;
2508 /* if they are both literal then */
2509 /* rewrite the tree */
2510 if (IS_LITERAL(RTYPE(tree)) &&
2511 IS_LITERAL(LTYPE(tree))) {
2512 tree->type = EX_VALUE ;
2513 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2514 valFromType(RETYPE(tree)),
2516 tree->right = tree->left = NULL;
2517 TETYPE(tree) = getSpec(TTYPE(tree) =
2518 tree->opval.val->type);
2521 LRVAL(tree) = RRVAL(tree) = 1;
2522 TTYPE(tree) = TETYPE(tree) = newCharLink();
2525 /*------------------------------------------------------------------*/
2526 /*----------------------------*/
2528 /*----------------------------*/
2529 case SIZEOF : /* evaluate wihout code generation */
2530 /* change the type to a integer */
2531 tree->type = EX_VALUE;
2532 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2533 tree->opval.val = constVal(buffer);
2534 tree->right = tree->left = NULL;
2535 TETYPE(tree) = getSpec(TTYPE(tree) =
2536 tree->opval.val->type);
2539 /*------------------------------------------------------------------*/
2540 /*----------------------------*/
2541 /* conditional operator '?' */
2542 /*----------------------------*/
2544 /* the type is one on the left */
2545 TTYPE(tree) = LTYPE(tree);
2546 TETYPE(tree)= getSpec (TTYPE(tree));
2550 /* if they don't match we have a problem */
2551 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2552 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2553 goto errorTreeReturn ;
2556 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2557 TETYPE(tree)= getSpec(TTYPE(tree));
2561 /*------------------------------------------------------------------*/
2562 /*----------------------------*/
2563 /* assignment operators */
2564 /*----------------------------*/
2567 /* for these it must be both must be integral */
2568 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2569 !IS_ARITHMETIC(RTYPE(tree))) {
2570 werror (E_OPS_INTEGRAL);
2571 goto errorTreeReturn ;
2574 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2576 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2577 werror(E_CODE_WRITE," ");
2580 werror(E_LVALUE_REQUIRED,"*= or /=");
2581 goto errorTreeReturn ;
2594 /* for these it must be both must be integral */
2595 if (!IS_INTEGRAL(LTYPE(tree)) ||
2596 !IS_INTEGRAL(RTYPE(tree))) {
2597 werror (E_OPS_INTEGRAL);
2598 goto errorTreeReturn ;
2601 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2603 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2604 werror(E_CODE_WRITE," ");
2607 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2608 goto errorTreeReturn ;
2616 /*------------------------------------------------------------------*/
2617 /*----------------------------*/
2619 /*----------------------------*/
2621 if (!(IS_PTR(LTYPE(tree)) ||
2622 IS_ARITHMETIC(LTYPE(tree)))) {
2623 werror(E_PLUS_INVALID,"-=");
2624 goto errorTreeReturn ;
2627 if (!(IS_PTR(RTYPE(tree)) ||
2628 IS_ARITHMETIC(RTYPE(tree)))) {
2629 werror(E_PLUS_INVALID,"-=");
2630 goto errorTreeReturn ;
2633 TETYPE(tree) = getSpec (TTYPE(tree) =
2634 computeType(LTYPE(tree),
2637 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2638 werror(E_CODE_WRITE," ");
2641 werror(E_LVALUE_REQUIRED,"-=");
2642 goto errorTreeReturn ;
2650 /*------------------------------------------------------------------*/
2651 /*----------------------------*/
2653 /*----------------------------*/
2655 /* this is not a unary operation */
2656 /* if both pointers then problem */
2657 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2658 werror(E_PTR_PLUS_PTR);
2659 goto errorTreeReturn ;
2662 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2663 werror(E_PLUS_INVALID,"+=");
2664 goto errorTreeReturn ;
2667 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2668 werror(E_PLUS_INVALID,"+=");
2669 goto errorTreeReturn;
2672 TETYPE(tree) = getSpec (TTYPE(tree) =
2673 computeType(LTYPE(tree),
2676 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2677 werror(E_CODE_WRITE," ");
2680 werror(E_LVALUE_REQUIRED,"+=");
2681 goto errorTreeReturn ;
2684 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2685 tree->opval.op = '=';
2691 /*------------------------------------------------------------------*/
2692 /*----------------------------*/
2693 /* straight assignemnt */
2694 /*----------------------------*/
2696 /* cannot be an aggregate */
2697 if (IS_AGGREGATE(LTYPE(tree))) {
2698 werror(E_AGGR_ASSIGN);
2699 goto errorTreeReturn;
2702 /* they should either match or be castable */
2703 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2704 werror(E_TYPE_MISMATCH,"assignment"," ");
2705 fprintf(stderr,"type --> '");
2706 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2707 fprintf(stderr,"assigned to type --> '");
2708 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2709 goto errorTreeReturn ;
2712 /* if the left side of the tree is of type void
2713 then report error */
2714 if (IS_VOID(LTYPE(tree))) {
2715 werror(E_CAST_ZERO);
2716 fprintf(stderr,"type --> '");
2717 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2718 fprintf(stderr,"assigned to type --> '");
2719 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2722 /* extra checks for pointer types */
2723 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2724 !IS_GENPTR(LTYPE(tree))) {
2725 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2726 werror(W_PTR_ASSIGN);
2729 TETYPE(tree) = getSpec(TTYPE(tree) =
2733 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2734 werror(E_CODE_WRITE," ");
2737 werror(E_LVALUE_REQUIRED,"=");
2738 goto errorTreeReturn ;
2745 /*------------------------------------------------------------------*/
2746 /*----------------------------*/
2747 /* comma operator */
2748 /*----------------------------*/
2750 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2753 /*------------------------------------------------------------------*/
2754 /*----------------------------*/
2756 /*----------------------------*/
2761 if (processParms (tree->left,
2763 tree->right,&parmNumber))
2764 goto errorTreeReturn ;
2766 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2767 tree->left->args = reverseVal(tree->left->args);
2768 reverseParms(tree->right);
2771 tree->args = tree->left->args ;
2772 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2775 /*------------------------------------------------------------------*/
2776 /*----------------------------*/
2777 /* return statement */
2778 /*----------------------------*/
2783 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2784 werror(E_RETURN_MISMATCH);
2785 goto errorTreeReturn ;
2788 if (IS_VOID(currFunc->type->next)
2790 !IS_VOID(RTYPE(tree))) {
2791 werror(E_FUNC_VOID);
2792 goto errorTreeReturn ;
2795 /* if there is going to be a casing required then add it */
2796 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2798 #if 0 && defined DEMAND_INTEGER_PROMOTION
2799 if (IS_INTEGRAL(currFunc->type->next))
2801 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2807 decorateType(newNode(CAST,
2808 newAst_LINK(copyLinkChain(currFunc->type->next)),
2818 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2819 werror(E_VOID_FUNC,currFunc->name);
2820 goto errorTreeReturn ;
2823 TTYPE(tree) = TETYPE(tree) = NULL ;
2826 /*------------------------------------------------------------------*/
2827 /*----------------------------*/
2828 /* switch statement */
2829 /*----------------------------*/
2831 /* the switch value must be an integer */
2832 if (!IS_INTEGRAL(LTYPE(tree))) {
2833 werror (E_SWITCH_NON_INTEGER);
2834 goto errorTreeReturn ;
2837 TTYPE(tree) = TETYPE(tree) = NULL ;
2840 /*------------------------------------------------------------------*/
2841 /*----------------------------*/
2843 /*----------------------------*/
2845 tree->left = backPatchLabels(tree->left,
2848 TTYPE(tree) = TETYPE(tree) = NULL;
2851 /*------------------------------------------------------------------*/
2852 /*----------------------------*/
2854 /*----------------------------*/
2857 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2858 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2859 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2861 /* if the for loop is reversible then
2862 reverse it otherwise do what we normally
2868 if (isLoopReversible (tree,&sym,&init,&end))
2869 return reverseLoop (tree,sym,init,end);
2871 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2872 AST_FOR(tree,continueLabel) ,
2873 AST_FOR(tree,falseLabel) ,
2874 AST_FOR(tree,condLabel) ,
2875 AST_FOR(tree,initExpr) ,
2876 AST_FOR(tree,condExpr) ,
2877 AST_FOR(tree,loopExpr),
2881 TTYPE(tree) = TETYPE(tree) = NULL ;
2885 /* some error found this tree will be killed */
2887 TTYPE(tree) = TETYPE(tree) = newCharLink();
2888 tree->opval.op = NULLOP ;
2894 /*-----------------------------------------------------------------*/
2895 /* sizeofOp - processes size of operation */
2896 /*-----------------------------------------------------------------*/
2897 value *sizeofOp( sym_link *type)
2901 /* get the size and convert it to character */
2902 sprintf (buff,"%d", getSize(type));
2904 /* now convert into value */
2905 return constVal (buff);
2909 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2910 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2911 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2912 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2913 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2914 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2915 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2917 /*-----------------------------------------------------------------*/
2918 /* backPatchLabels - change and or not operators to flow control */
2919 /*-----------------------------------------------------------------*/
2920 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2926 if ( ! (IS_ANDORNOT(tree)))
2929 /* if this an and */
2931 static int localLbl = 0 ;
2932 symbol *localLabel ;
2934 sprintf (buffer,"_and_%d",localLbl++);
2935 localLabel = newSymbol(buffer,NestLevel);
2937 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2939 /* if left is already a IFX then just change the if true label in that */
2940 if (!IS_IFX(tree->left))
2941 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2943 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2944 /* right is a IFX then just join */
2945 if (IS_IFX(tree->right))
2946 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2948 tree->right = createLabel(localLabel,tree->right);
2949 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2951 return newNode(NULLOP,tree->left,tree->right);
2954 /* if this is an or operation */
2956 static int localLbl = 0 ;
2957 symbol *localLabel ;
2959 sprintf (buffer,"_or_%d",localLbl++);
2960 localLabel = newSymbol(buffer,NestLevel);
2962 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2964 /* if left is already a IFX then just change the if true label in that */
2965 if (!IS_IFX(tree->left))
2966 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2968 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2969 /* right is a IFX then just join */
2970 if (IS_IFX(tree->right))
2971 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2973 tree->right = createLabel(localLabel,tree->right);
2974 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2976 return newNode(NULLOP,tree->left,tree->right);
2981 int wasnot = IS_NOT(tree->left);
2982 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2984 /* if the left is already a IFX */
2985 if ( ! IS_IFX(tree->left) )
2986 tree->left = newNode (IFX,tree->left,NULL);
2989 tree->left->trueLabel = trueLabel ;
2990 tree->left->falseLabel= falseLabel ;
2992 tree->left->trueLabel = falseLabel ;
2993 tree->left->falseLabel= trueLabel ;
2999 tree->trueLabel = trueLabel ;
3000 tree->falseLabel= falseLabel;
3007 /*-----------------------------------------------------------------*/
3008 /* createBlock - create expression tree for block */
3009 /*-----------------------------------------------------------------*/
3010 ast *createBlock ( symbol *decl, ast *body )
3014 /* if the block has nothing */
3018 ex = newNode(BLOCK,NULL,body);
3019 ex->values.sym = decl ;
3021 ex->right = ex->right ;
3027 /*-----------------------------------------------------------------*/
3028 /* createLabel - creates the expression tree for labels */
3029 /*-----------------------------------------------------------------*/
3030 ast *createLabel ( symbol *label, ast *stmnt )
3033 char name[SDCC_NAME_MAX+1];
3036 /* must create fresh symbol if the symbol name */
3037 /* exists in the symbol table, since there can */
3038 /* be a variable with the same name as the labl */
3039 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
3040 (csym->level == label->level))
3041 label = newSymbol(label->name,label->level);
3043 /* change the name before putting it in add _*/
3044 sprintf (name,"%s",label->name);
3046 /* put the label in the LabelSymbol table */
3047 /* but first check if a label of the same */
3049 if ( (csym = findSym(LabelTab,NULL,name)))
3050 werror(E_DUPLICATE_LABEL,label->name);
3052 addSym (LabelTab, label, name,label->level,0);
3055 label->key = labelKey++ ;
3056 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3062 /*-----------------------------------------------------------------*/
3063 /* createCase - generates the parsetree for a case statement */
3064 /*-----------------------------------------------------------------*/
3065 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
3067 char caseLbl[SDCC_NAME_MAX+1];
3071 /* if the switch statement does not exist */
3072 /* then case is out of context */
3074 werror(E_CASE_CONTEXT);
3078 caseVal = decorateType(resolveSymbols(caseVal));
3079 /* if not a constant then error */
3080 if (!IS_LITERAL(caseVal->ftype)) {
3081 werror(E_CASE_CONSTANT);
3085 /* if not a integer than error */
3086 if (!IS_INTEGRAL(caseVal->ftype)) {
3087 werror(E_CASE_NON_INTEGER);
3091 /* find the end of the switch values chain */
3092 if (!(val = swStat->values.switchVals.swVals))
3093 swStat->values.switchVals.swVals = caseVal->opval.val ;
3095 /* also order the cases according to value */
3097 int cVal = (int) floatFromVal(caseVal->opval.val);
3098 while (val && (int) floatFromVal(val) < cVal) {
3103 /* if we reached the end then */
3105 pval->next = caseVal->opval.val;
3107 /* we found a value greater than */
3108 /* the current value we must add this */
3109 /* before the value */
3110 caseVal->opval.val->next = val;
3112 /* if this was the first in chain */
3113 if (swStat->values.switchVals.swVals == val)
3114 swStat->values.switchVals.swVals =
3117 pval->next = caseVal->opval.val;
3122 /* create the case label */
3123 sprintf(caseLbl,"_case_%d_%d",
3124 swStat->values.switchVals.swNum,
3125 (int) floatFromVal(caseVal->opval.val));
3127 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3132 /*-----------------------------------------------------------------*/
3133 /* createDefault - creates the parse tree for the default statement*/
3134 /*-----------------------------------------------------------------*/
3135 ast *createDefault (ast *swStat, ast *stmnt)
3137 char defLbl[SDCC_NAME_MAX+1];
3139 /* if the switch statement does not exist */
3140 /* then case is out of context */
3142 werror(E_CASE_CONTEXT);
3146 /* turn on the default flag */
3147 swStat->values.switchVals.swDefault = 1 ;
3149 /* create the label */
3150 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3151 return createLabel(newSymbol(defLbl,0),stmnt);
3154 /*-----------------------------------------------------------------*/
3155 /* createIf - creates the parsetree for the if statement */
3156 /*-----------------------------------------------------------------*/
3157 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3159 static int Lblnum = 0 ;
3161 symbol *ifTrue , *ifFalse, *ifEnd ;
3163 /* if neither exists */
3164 if (! elseBody && !ifBody)
3167 /* create the labels */
3168 sprintf (buffer,"_iffalse_%d",Lblnum);
3169 ifFalse = newSymbol (buffer,NestLevel);
3170 /* if no else body then end == false */
3174 sprintf (buffer,"_ifend_%d",Lblnum);
3175 ifEnd = newSymbol (buffer,NestLevel);
3178 sprintf (buffer,"_iftrue_%d",Lblnum);
3179 ifTrue = newSymbol (buffer,NestLevel);
3183 /* attach the ifTrue label to the top of it body */
3184 ifBody = createLabel(ifTrue,ifBody);
3185 /* attach a goto end to the ifBody if else is present */
3187 ifBody = newNode(NULLOP,ifBody,
3189 newAst_VALUE(symbolVal(ifEnd)),
3191 /* put the elseLabel on the else body */
3192 elseBody = createLabel (ifFalse,elseBody);
3193 /* out the end at the end of the body */
3194 elseBody = newNode(NULLOP,
3196 createLabel(ifEnd,NULL));
3199 ifBody = newNode(NULLOP,ifBody,
3200 createLabel(ifFalse,NULL));
3202 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3203 if (IS_IFX(condAst))
3206 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3208 return newNode(NULLOP,ifTree,
3209 newNode(NULLOP,ifBody,elseBody));
3213 /*-----------------------------------------------------------------*/
3214 /* createDo - creates parse tree for do */
3217 /* _docontinue_n: */
3218 /* condition_expression +-> trueLabel -> _dobody_n */
3220 /* +-> falseLabel-> _dobreak_n */
3222 /*-----------------------------------------------------------------*/
3223 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3224 symbol *falseLabel, ast *condAst, ast *doBody )
3229 /* if the body does not exist then it is simple */
3231 condAst = backPatchLabels(condAst,continueLabel,NULL);
3232 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3233 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3234 doTree->trueLabel = continueLabel ;
3235 doTree->falseLabel= NULL ;
3239 /* otherwise we have a body */
3240 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3242 /* attach the body label to the top */
3243 doBody = createLabel(trueLabel,doBody);
3244 /* attach the continue label to end of body */
3245 doBody = newNode(NULLOP, doBody,
3246 createLabel(continueLabel,NULL));
3248 /* now put the break label at the end */
3249 if (IS_IFX(condAst))
3252 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3254 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3256 /* putting it together */
3257 return newNode(NULLOP,doBody,doTree);
3260 /*-----------------------------------------------------------------*/
3261 /* createFor - creates parse tree for 'for' statement */
3264 /* condExpr +-> trueLabel -> _forbody_n */
3266 /* +-> falseLabel-> _forbreak_n */
3269 /* _forcontinue_n: */
3271 /* goto _forcond_n ; */
3273 /*-----------------------------------------------------------------*/
3274 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3275 symbol *falseLabel,symbol *condLabel ,
3276 ast *initExpr, ast *condExpr, ast *loopExpr,
3281 /* if loopexpression not present then we can generate it */
3282 /* the same way as a while */
3284 return newNode(NULLOP,initExpr,
3285 createWhile (trueLabel, continueLabel,
3286 falseLabel,condExpr, forBody ));
3287 /* vanilla for statement */
3288 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3290 if (condExpr && !IS_IFX(condExpr))
3291 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3294 /* attach condition label to condition */
3295 condExpr = createLabel(condLabel,condExpr);
3297 /* attach body label to body */
3298 forBody = createLabel(trueLabel,forBody);
3300 /* attach continue to forLoop expression & attach */
3301 /* goto the forcond @ and of loopExpression */
3302 loopExpr = createLabel(continueLabel,
3306 newAst_VALUE(symbolVal(condLabel)),
3308 /* now start putting them together */
3309 forTree = newNode(NULLOP,initExpr,condExpr);
3310 forTree = newNode(NULLOP,forTree,forBody);
3311 forTree = newNode(NULLOP,forTree,loopExpr);
3312 /* finally add the break label */
3313 forTree = newNode(NULLOP,forTree,
3314 createLabel(falseLabel,NULL));
3318 /*-----------------------------------------------------------------*/
3319 /* createWhile - creates parse tree for while statement */
3320 /* the while statement will be created as follows */
3322 /* _while_continue_n: */
3323 /* condition_expression +-> trueLabel -> _while_boby_n */
3325 /* +-> falseLabel -> _while_break_n*/
3326 /* _while_body_n: */
3328 /* goto _while_continue_n */
3329 /* _while_break_n: */
3330 /*-----------------------------------------------------------------*/
3331 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3332 symbol *falseLabel,ast *condExpr, ast *whileBody )
3336 /* put the continue label */
3337 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3338 condExpr = createLabel(continueLabel,condExpr);
3339 condExpr->lineno = 0;
3341 /* put the body label in front of the body */
3342 whileBody = createLabel(trueLabel,whileBody);
3343 whileBody->lineno = 0;
3344 /* put a jump to continue at the end of the body */
3345 /* and put break label at the end of the body */
3346 whileBody = newNode(NULLOP,
3349 newAst_VALUE(symbolVal(continueLabel)),
3350 createLabel(falseLabel,NULL)));
3352 /* put it all together */
3353 if ( IS_IFX(condExpr) )
3354 whileTree = condExpr ;
3356 whileTree = newNode (IFX, condExpr,NULL );
3357 /* put the true & false labels in place */
3358 whileTree->trueLabel = trueLabel ;
3359 whileTree->falseLabel= falseLabel;
3362 return newNode(NULLOP,whileTree,whileBody );
3365 /*-----------------------------------------------------------------*/
3366 /* optimizeGetHbit - get highest order bit of the expression */
3367 /*-----------------------------------------------------------------*/
3368 ast *optimizeGetHbit (ast *tree)
3371 /* if this is not a bit and */
3372 if (!IS_BITAND(tree))
3375 /* will look for tree of the form
3376 ( expr >> ((sizeof expr) -1) ) & 1 */
3377 if (!IS_AST_LIT_VALUE(tree->right))
3380 if (AST_LIT_VALUE(tree->right) != 1)
3383 if (!IS_RIGHT_OP(tree->left))
3386 if (!IS_AST_LIT_VALUE(tree->left->right))
3389 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3390 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3393 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3397 /*-----------------------------------------------------------------*/
3398 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3399 /*-----------------------------------------------------------------*/
3400 ast *optimizeRRCRLC ( ast *root )
3402 /* will look for trees of the form
3403 (?expr << 1) | (?expr >> 7) or
3404 (?expr >> 7) | (?expr << 1) will make that
3405 into a RLC : operation ..
3407 (?expr >> 1) | (?expr << 7) or
3408 (?expr << 7) | (?expr >> 1) will make that
3409 into a RRC operation
3410 note : by 7 I mean (number of bits required to hold the
3412 /* if the root operations is not a | operation the not */
3413 if (!IS_BITOR(root))
3416 /* I have to think of a better way to match patterns this sucks */
3417 /* that aside let start looking for the first case : I use a the
3418 negative check a lot to improve the efficiency */
3419 /* (?expr << 1) | (?expr >> 7) */
3420 if (IS_LEFT_OP(root->left) &&
3421 IS_RIGHT_OP(root->right) ) {
3423 if (!SPEC_USIGN(TETYPE(root->left->left)))
3426 if (!IS_AST_LIT_VALUE(root->left->right) ||
3427 !IS_AST_LIT_VALUE(root->right->right))
3430 /* make sure it is the same expression */
3431 if (!isAstEqual(root->left->left,
3435 if (AST_LIT_VALUE(root->left->right) != 1 )
3438 if (AST_LIT_VALUE(root->right->right) !=
3439 (getSize(TTYPE(root->left->left))*8 - 1))
3442 /* whew got the first case : create the AST */
3443 return newNode(RLC,root->left->left,NULL);
3447 /* check for second case */
3448 /* (?expr >> 7) | (?expr << 1) */
3449 if (IS_LEFT_OP(root->right) &&
3450 IS_RIGHT_OP(root->left) ) {
3452 if (!SPEC_USIGN(TETYPE(root->left->left)))
3455 if (!IS_AST_LIT_VALUE(root->left->right) ||
3456 !IS_AST_LIT_VALUE(root->right->right))
3459 /* make sure it is the same symbol */
3460 if (!isAstEqual(root->left->left,
3464 if (AST_LIT_VALUE(root->right->right) != 1 )
3467 if (AST_LIT_VALUE(root->left->right) !=
3468 (getSize(TTYPE(root->left->left))*8 - 1))
3471 /* whew got the first case : create the AST */
3472 return newNode(RLC,root->left->left,NULL);
3477 /* third case for RRC */
3478 /* (?symbol >> 1) | (?symbol << 7) */
3479 if (IS_LEFT_OP(root->right) &&
3480 IS_RIGHT_OP(root->left) ) {
3482 if (!SPEC_USIGN(TETYPE(root->left->left)))
3485 if (!IS_AST_LIT_VALUE(root->left->right) ||
3486 !IS_AST_LIT_VALUE(root->right->right))
3489 /* make sure it is the same symbol */
3490 if (!isAstEqual(root->left->left,
3494 if (AST_LIT_VALUE(root->left->right) != 1 )
3497 if (AST_LIT_VALUE(root->right->right) !=
3498 (getSize(TTYPE(root->left->left))*8 - 1))
3501 /* whew got the first case : create the AST */
3502 return newNode(RRC,root->left->left,NULL);
3506 /* fourth and last case for now */
3507 /* (?symbol << 7) | (?symbol >> 1) */
3508 if (IS_RIGHT_OP(root->right) &&
3509 IS_LEFT_OP(root->left) ) {
3511 if (!SPEC_USIGN(TETYPE(root->left->left)))
3514 if (!IS_AST_LIT_VALUE(root->left->right) ||
3515 !IS_AST_LIT_VALUE(root->right->right))
3518 /* make sure it is the same symbol */
3519 if (!isAstEqual(root->left->left,
3523 if (AST_LIT_VALUE(root->right->right) != 1 )
3526 if (AST_LIT_VALUE(root->left->right) !=
3527 (getSize(TTYPE(root->left->left))*8 - 1))
3530 /* whew got the first case : create the AST */
3531 return newNode(RRC,root->left->left,NULL);
3535 /* not found return root */
3539 /*-----------------------------------------------------------------*/
3540 /* optimizeCompare - otimizes compares for bit variables */
3541 /*-----------------------------------------------------------------*/
3542 ast *optimizeCompare ( ast *root )
3544 ast *optExpr = NULL;
3547 unsigned int litValue ;
3549 /* if nothing then return nothing */
3553 /* if not a compare op then do leaves */
3554 if (!IS_COMPARE_OP(root)) {
3555 root->left = optimizeCompare (root->left);
3556 root->right= optimizeCompare (root->right);
3560 /* if left & right are the same then depending
3561 of the operation do */
3562 if (isAstEqual(root->left,root->right)) {
3563 switch (root->opval.op) {
3567 optExpr = newAst_VALUE(constVal("0"));
3572 optExpr = newAst_VALUE(constVal("1"));
3576 return decorateType(optExpr);
3579 vleft = (root->left->type == EX_VALUE ?
3580 root->left->opval.val : NULL );
3582 vright = (root->right->type == EX_VALUE ?
3583 root->right->opval.val : NULL);
3585 /* if left is a BITVAR in BITSPACE */
3586 /* and right is a LITERAL then opt-*/
3587 /* imize else do nothing */
3588 if (vleft && vright &&
3589 IS_BITVAR(vleft->etype) &&
3590 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3591 IS_LITERAL(vright->etype)) {
3593 /* if right side > 1 then comparison may never succeed */
3594 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3595 werror(W_BAD_COMPARE);
3600 switch (root->opval.op) {
3601 case '>' : /* bit value greater than 1 cannot be */
3602 werror(W_BAD_COMPARE);
3606 case '<' : /* bit value < 1 means 0 */
3608 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3611 case LE_OP : /* bit value <= 1 means no check */
3612 optExpr = newAst_VALUE(vright);
3615 case GE_OP : /* bit value >= 1 means only check for = */
3617 optExpr = newAst_VALUE(vleft);
3620 } else { /* literal is zero */
3621 switch (root->opval.op) {
3622 case '<' : /* bit value < 0 cannot be */
3623 werror(W_BAD_COMPARE);
3627 case '>' : /* bit value > 0 means 1 */
3629 optExpr = newAst_VALUE(vleft);
3632 case LE_OP : /* bit value <= 0 means no check */
3633 case GE_OP : /* bit value >= 0 means no check */
3634 werror(W_BAD_COMPARE);
3638 case EQ_OP : /* bit == 0 means ! of bit */
3639 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3643 return decorateType(resolveSymbols(optExpr));
3644 } /* end-of-if of BITVAR */
3649 /*-----------------------------------------------------------------*/
3650 /* addSymToBlock : adds the symbol to the first block we find */
3651 /*-----------------------------------------------------------------*/
3652 void addSymToBlock (symbol *sym, ast *tree)
3654 /* reached end of tree or a leaf */
3655 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3659 if (IS_AST_OP(tree) &&
3660 tree->opval.op == BLOCK ) {
3662 symbol *lsym = copySymbol(sym);
3664 lsym->next = AST_VALUES(tree,sym);
3665 AST_VALUES(tree,sym) = lsym ;
3669 addSymToBlock(sym,tree->left);
3670 addSymToBlock(sym,tree->right);
3673 /*-----------------------------------------------------------------*/
3674 /* processRegParms - do processing for register parameters */
3675 /*-----------------------------------------------------------------*/
3676 static void processRegParms (value *args, ast *body)
3679 if (IS_REGPARM(args->etype))
3680 addSymToBlock(args->sym,body);
3685 /*-----------------------------------------------------------------*/
3686 /* resetParmKey - resets the operandkeys for the symbols */
3687 /*-----------------------------------------------------------------*/
3688 DEFSETFUNC(resetParmKey)
3699 /*-----------------------------------------------------------------*/
3700 /* createFunction - This is the key node that calls the iCode for */
3701 /* generating the code for a function. Note code */
3702 /* is generated function by function, later when */
3703 /* add inter-procedural analysis this will change */
3704 /*-----------------------------------------------------------------*/
3705 ast *createFunction (symbol *name, ast *body )
3711 iCode *piCode = NULL;
3713 /* if check function return 0 then some problem */
3714 if (checkFunction (name) == 0)
3717 /* create a dummy block if none exists */
3719 body = newNode(BLOCK,NULL,NULL);
3723 /* check if the function name already in the symbol table */
3724 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3726 /* special case for compiler defined functions
3727 we need to add the name to the publics list : this
3728 actually means we are now compiling the compiler
3731 addSet(&publics,name);
3736 allocVariables(name);
3738 name->lastLine = yylineno;
3740 processFuncArgs(currFunc,0);
3742 /* set the stack pointer */
3743 /* PENDING: check this for the mcs51 */
3744 stackPtr = -port->stack.direction * port->stack.call_overhead;
3745 if (IS_ISR(name->etype))
3746 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3747 if (IS_RENT(name->etype) || options.stackAuto)
3748 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3750 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3752 fetype = getSpec(name->type); /* get the specifier for the function */
3753 /* if this is a reentrant function then */
3754 if (IS_RENT(fetype))
3757 allocParms (name->args); /* allocate the parameters */
3759 /* do processing for parameters that are passed in registers */
3760 processRegParms (name->args,body);
3762 /* set the stack pointer */
3766 /* allocate & autoinit the block variables */
3767 processBlockVars (body, &stack,ALLOCATE);
3769 /* save the stack information */
3770 if (options.useXstack)
3771 name->xstack = SPEC_STAK(fetype) = stack;
3773 name->stack = SPEC_STAK(fetype) = stack;
3775 /* name needs to be mangled */
3776 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3778 body = resolveSymbols(body); /* resolve the symbols */
3779 body = decorateType (body); /* propagateType & do semantic checks */
3781 ex = newAst_VALUE(symbolVal(name)); /* create name */
3782 ex = newNode (FUNCTION,ex,body);
3783 ex->values.args = name->args ;
3786 werror(E_FUNC_NO_CODE,name->name);
3790 /* create the node & generate intermediate code */
3791 codeOutFile = code->oFile;
3792 piCode = iCodeFromAst(ex);
3795 werror(E_FUNC_NO_CODE,name->name);
3799 eBBlockFromiCode(piCode);
3801 /* if there are any statics then do them */
3803 codeOutFile = statsg->oFile;
3804 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3810 /* dealloc the block variables */
3811 processBlockVars(body, &stack,DEALLOCATE);
3812 /* deallocate paramaters */
3813 deallocParms(name->args);
3815 if (IS_RENT(fetype))
3818 /* we are done freeup memory & cleanup */
3823 addSet(&operKeyReset,name);
3824 applyToSet(operKeyReset,resetParmKey);
3826 if (options.debug && !options.nodebug)
3827 cdbStructBlock(1,cdbFile);
3829 cleanUpLevel(LabelTab,0);
3830 cleanUpBlock(StructTab,1);
3831 cleanUpBlock(TypedefTab,1);
3833 xstack->syms = NULL;
3834 istack->syms = NULL;