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);
637 /* if defined parameters ended but actual has not & */
639 if (! defParm && actParm &&
640 (options.stackAuto || IS_RENT(fetype)))
643 resolveSymbols(actParm);
644 /* if this is a PARAM node then match left & right */
645 if ( actParm->type == EX_OP && actParm->opval.op == PARAM) {
647 return (processParms (func,defParm,actParm->left,parmNumber) ||
648 processParms (func,defParm->next, actParm->right,parmNumber) );
651 /* the parameter type must be atleast castable */
652 if (checkType(defParm->type,actParm->ftype) == 0) {
653 werror(E_TYPE_MISMATCH_PARM,*parmNumber);
654 werror(E_CONTINUE,"defined type ");
655 printTypeChain(defParm->type,stderr);fprintf(stderr,"\n");
656 werror(E_CONTINUE,"actual type ");
657 printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n");
660 /* if the parameter is castable then add the cast */
661 if ( checkType (defParm->type,actParm->ftype) < 0) {
662 ast *pTree = resolveSymbols(copyAst(actParm));
664 /* now change the current one to a cast */
665 actParm->type = EX_OP ;
666 actParm->opval.op = CAST ;
667 actParm->left = newAst_LINK(defParm->type);
668 actParm->right= pTree ;
669 actParm->etype= defParm->etype;
670 actParm->ftype= defParm->type;
673 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
675 actParm->argSym = defParm->sym;
676 /* make a copy and change the regparm type to the defined parm */
677 actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype));
678 SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype);
682 /*-----------------------------------------------------------------*/
683 /* createIvalType - generates ival for basic types */
684 /*-----------------------------------------------------------------*/
685 ast *createIvalType ( ast *sym,sym_link *type, initList *ilist)
689 /* if initList is deep */
690 if ( ilist->type == INIT_DEEP )
691 ilist = ilist->init.deep ;
693 iExpr = decorateType(resolveSymbols(list2expr(ilist)));
694 return decorateType(newNode('=',sym,iExpr));
697 /*-----------------------------------------------------------------*/
698 /* createIvalStruct - generates initial value for structures */
699 /*-----------------------------------------------------------------*/
700 ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist)
706 sflds = SPEC_STRUCT(type)->fields ;
707 if (ilist->type != INIT_DEEP) {
708 werror(E_INIT_STRUCT,"");
712 iloop = ilist->init.deep;
714 for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) {
717 /* if we have come to end */
721 lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds)));
722 lAst = decorateType(resolveSymbols(lAst));
723 rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast)));
729 /*-----------------------------------------------------------------*/
730 /* createIvalArray - generates code for array initialization */
731 /*-----------------------------------------------------------------*/
732 ast *createIvalArray (ast *sym, sym_link *type, initList *ilist)
736 int lcnt = 0, size =0 ;
738 /* take care of the special case */
739 /* array of characters can be init */
741 if ( IS_CHAR(type->next) )
742 if ( (rast = createIvalCharPtr(sym,
744 decorateType(resolveSymbols(list2expr(ilist))))))
746 return decorateType(resolveSymbols(rast));
748 /* not the special case */
749 if (ilist->type != INIT_DEEP) {
750 werror(E_INIT_STRUCT,"");
754 iloop = ilist->init.deep ;
755 lcnt = DCL_ELEM(type);
761 aSym = newNode('[',sym,newAst_VALUE(valueFromLit(size-1)));
762 aSym = decorateType(resolveSymbols(aSym));
763 rast = createIval (aSym,type->next,iloop,rast) ;
764 iloop = (iloop ? iloop->next : NULL) ;
767 /* if not array limits given & we */
768 /* are out of initialisers then */
769 if (!DCL_ELEM(type) && !iloop)
772 /* no of elements given and we */
773 /* have generated for all of them */
778 /* if we have not been given a size */
780 DCL_ELEM(type) = size;
782 return decorateType(resolveSymbols(rast));
786 /*-----------------------------------------------------------------*/
787 /* createIvalCharPtr - generates initial values for char pointers */
788 /*-----------------------------------------------------------------*/
789 ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr)
793 /* if this is a pointer & right is a literal array then */
794 /* just assignment will do */
795 if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) ||
796 SPEC_SCLS(iexpr->etype) == S_CODE )
797 && IS_ARRAY(iexpr->ftype)))
798 return newNode('=',sym,iexpr);
800 /* left side is an array so we have to assign each */
802 if (( IS_LITERAL(iexpr->etype) ||
803 SPEC_SCLS(iexpr->etype) == S_CODE )
804 && IS_ARRAY(iexpr->ftype)) {
806 /* for each character generate an assignment */
807 /* to the array element */
808 char *s = SPEC_CVAL(iexpr->etype).v_char ;
812 rast = newNode(NULLOP,
816 newAst_VALUE(valueFromLit(i))),
817 newAst_VALUE(valueFromLit(*s))));
821 rast = newNode(NULLOP,
825 newAst_VALUE(valueFromLit(i))),
826 newAst_VALUE(valueFromLit(*s))));
827 return decorateType(resolveSymbols(rast));
833 /*-----------------------------------------------------------------*/
834 /* createIvalPtr - generates initial value for pointers */
835 /*-----------------------------------------------------------------*/
836 ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist)
842 if ( ilist->type == INIT_DEEP )
843 ilist = ilist->init.deep ;
845 iexpr = decorateType(resolveSymbols(list2expr(ilist)));
847 /* if character pointer */
848 if (IS_CHAR(type->next))
849 if ((rast = createIvalCharPtr (sym,type,iexpr)))
852 return newNode('=',sym,iexpr);
855 /*-----------------------------------------------------------------*/
856 /* createIval - generates code for initial value */
857 /*-----------------------------------------------------------------*/
858 ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid)
865 /* if structure then */
867 rast = createIvalStruct(sym, type,ilist);
869 /* if this is a pointer */
871 rast = createIvalPtr(sym, type,ilist);
873 /* if this is an array */
875 rast = createIvalArray(sym, type,ilist);
877 /* if type is SPECIFIER */
879 rast = createIvalType (sym,type,ilist);
881 return decorateType(resolveSymbols(newNode(NULLOP,wid,rast)));
883 return decorateType(resolveSymbols(rast)) ;
886 /*-----------------------------------------------------------------*/
887 /* initAggregates - initialises aggregate variables with initv */
888 /*-----------------------------------------------------------------*/
889 ast *initAggregates ( symbol *sym, initList *ival, ast *wid)
891 return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid);
894 /*-----------------------------------------------------------------*/
895 /* gatherAutoInit - creates assignment expressions for initial */
897 /*-----------------------------------------------------------------*/
898 ast *gatherAutoInit ( symbol *autoChain )
905 for ( sym = autoChain ; sym ; sym = sym->next ) {
907 /* resolve the symbols in the ival */
909 resolveIvalSym(sym->ival);
911 /* if this is a static variable & has an */
912 /* initial value the code needs to be lifted */
913 /* here to the main portion since they can be */
914 /* initialised only once at the start */
915 if ( IS_STATIC(sym->etype) && sym->ival &&
916 SPEC_SCLS(sym->etype) != S_CODE) {
919 /* insert the symbol into the symbol table */
920 /* with level = 0 & name = rname */
921 newSym = copySymbol (sym);
922 addSym (SymbolTab,newSym,newSym->name,0,0);
924 /* now lift the code to main */
925 if (IS_AGGREGATE(sym->type))
926 work = initAggregates (sym, sym->ival,NULL);
928 work = newNode('=' ,newAst_VALUE(symbolVal(newSym)),
929 list2expr(sym->ival));
931 setAstLineno(work,sym->lineDef);
935 staticAutos = newNode(NULLOP,staticAutos,work);
942 /* if there is an initial value */
943 if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) {
944 if (IS_AGGREGATE(sym->type))
945 work = initAggregates (sym,sym->ival,NULL);
947 work = newNode('=' ,newAst_VALUE(symbolVal(sym)),
948 list2expr(sym->ival));
950 setAstLineno (work,sym->lineDef);
953 init = newNode(NULLOP,init,work);
962 /*-----------------------------------------------------------------*/
963 /* stringToSymbol - creates a symbol from a literal string */
964 /*-----------------------------------------------------------------*/
965 static value *stringToSymbol (value *val)
967 char name[SDCC_NAME_MAX+1];
968 static int charLbl = 0;
971 sprintf(name,"_str_%d",charLbl++);
972 sym = newSymbol(name,0); /* make it @ level 0 */
973 strcpy(sym->rname,name);
975 /* copy the type from the value passed */
976 sym->type = copyLinkChain(val->type);
977 sym->etype = getSpec(sym->type);
978 /* change to storage class & output class */
979 SPEC_SCLS(sym->etype) = S_CODE ;
980 SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ;
981 SPEC_STAT(sym->etype) = 1;
982 /* make the level & block = 0 */
983 sym->block = sym->level = 0;
986 sym->ival = newiList(INIT_NODE,newAst_VALUE(val));
993 return symbolVal(sym);
997 /*-----------------------------------------------------------------*/
998 /* processBlockVars - will go thru the ast looking for block if */
999 /* a block is found then will allocate the syms */
1000 /* will also gather the auto inits present */
1001 /*-----------------------------------------------------------------*/
1002 ast *processBlockVars ( ast *tree , int *stack, int action)
1007 /* if this is a block */
1008 if (tree->type == EX_OP && tree->opval.op == BLOCK ) {
1011 if (action == ALLOCATE) {
1012 autoInit = gatherAutoInit (tree->values.sym);
1013 *stack += allocVariables (tree->values.sym);
1015 /* if there are auto inits then do them */
1017 tree->left = newNode(NULLOP,autoInit,tree->left);
1018 } else /* action is deallocate */
1019 deallocLocal (tree->values.sym) ;
1022 processBlockVars (tree->left, stack, action);
1023 processBlockVars (tree->right, stack, action);
1027 /*-----------------------------------------------------------------*/
1028 /* constExprValue - returns the value of a constant expression */
1029 /*-----------------------------------------------------------------*/
1030 value *constExprValue (ast *cexpr, int check)
1032 cexpr = decorateType(resolveSymbols(cexpr));
1034 /* if this is not a constant then */
1035 if (!IS_LITERAL(cexpr->ftype)) {
1036 /* then check if this is a literal array
1038 if (SPEC_SCLS(cexpr->etype) == S_CODE &&
1039 SPEC_CVAL(cexpr->etype).v_char &&
1040 IS_ARRAY(cexpr->ftype)) {
1041 value *val = valFromType(cexpr->ftype);
1042 SPEC_SCLS(val->etype) = S_LITERAL;
1043 val->sym =cexpr->opval.val->sym ;
1044 val->sym->type = copyLinkChain(cexpr->ftype);
1045 val->sym->etype = getSpec(val->sym->type);
1046 strcpy(val->name,cexpr->opval.val->sym->rname);
1050 /* if we are casting a literal value then */
1051 if (IS_AST_OP(cexpr) &&
1052 cexpr->opval.op == CAST &&
1053 IS_LITERAL(cexpr->left->ftype))
1054 return valCastLiteral(cexpr->ftype,
1055 floatFromVal(cexpr->left->opval.val));
1057 if (IS_AST_VALUE(cexpr))
1058 return cexpr->opval.val;
1061 werror(E_CONST_EXPECTED,"found expression");
1066 /* return the value */
1067 return cexpr->opval.val ;
1071 /*-----------------------------------------------------------------*/
1072 /* isLabelInAst - will return true if a given label is found */
1073 /*-----------------------------------------------------------------*/
1074 bool isLabelInAst (symbol *label, ast *tree)
1076 if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree))
1079 if (IS_AST_OP(tree) &&
1080 tree->opval.op == LABEL &&
1081 isSymbolEqual(AST_SYMBOL(tree->left),label))
1084 return isLabelInAst(label,tree->right) &&
1085 isLabelInAst(label,tree->left);
1089 /*-----------------------------------------------------------------*/
1090 /* isLoopCountable - return true if the loop count can be determi- */
1091 /* -ned at compile time . */
1092 /*-----------------------------------------------------------------*/
1093 bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr,
1094 symbol **sym,ast **init, ast **end)
1097 /* the loop is considered countable if the following
1098 conditions are true :-
1100 a) initExpr :- <sym> = <const>
1101 b) condExpr :- <sym> < <const1>
1102 c) loopExpr :- <sym> ++
1105 /* first check the initExpr */
1106 if ( IS_AST_OP(initExpr) &&
1107 initExpr->opval.op == '=' && /* is assignment */
1108 IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */
1110 *sym = AST_SYMBOL(initExpr->left);
1111 *init= initExpr->right;
1116 /* for now the symbol has to be of
1118 if (!IS_INTEGRAL((*sym)->type))
1121 /* now check condExpr */
1122 if (IS_AST_OP(condExpr)) {
1124 switch (condExpr->opval.op) {
1126 if (IS_AST_SYM_VALUE(condExpr->left) &&
1127 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) &&
1128 IS_AST_LIT_VALUE(condExpr->right)) {
1129 *end = condExpr->right;
1135 if (IS_AST_OP(condExpr->left) &&
1136 condExpr->left->opval.op == '>' &&
1137 IS_AST_LIT_VALUE(condExpr->left->right) &&
1138 IS_AST_SYM_VALUE(condExpr->left->left)&&
1139 isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) {
1141 *end = newNode('+', condExpr->left->right,
1142 newAst_VALUE(constVal("1")));
1153 /* check loop expression is of the form <sym>++ */
1154 if (!IS_AST_OP(loopExpr))
1157 /* check if <sym> ++ */
1158 if (loopExpr->opval.op == INC_OP) {
1160 if (loopExpr->left) {
1162 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1163 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)))
1168 if (IS_AST_SYM_VALUE(loopExpr->right) &&
1169 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right)))
1176 if ( loopExpr->opval.op == ADD_ASSIGN ) {
1178 if (IS_AST_SYM_VALUE(loopExpr->left) &&
1179 isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) &&
1180 IS_AST_LIT_VALUE(loopExpr->right) &&
1181 (int)AST_LIT_VALUE(loopExpr->right) != 1)
1189 /*-----------------------------------------------------------------*/
1190 /* astHasVolatile - returns true if ast contains any volatile */
1191 /*-----------------------------------------------------------------*/
1192 bool astHasVolatile (ast *tree)
1197 if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree)))
1200 if (IS_AST_OP(tree))
1201 return astHasVolatile(tree->left) ||
1202 astHasVolatile(tree->right);
1207 /*-----------------------------------------------------------------*/
1208 /* astHasPointer - return true if the ast contains any ptr variable*/
1209 /*-----------------------------------------------------------------*/
1210 bool astHasPointer (ast *tree)
1215 if (IS_AST_LINK(tree))
1218 /* if we hit an array expression then check
1219 only the left side */
1220 if (IS_AST_OP(tree) && tree->opval.op == '[')
1221 return astHasPointer(tree->left);
1223 if (IS_AST_VALUE(tree))
1224 return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype);
1226 return astHasPointer(tree->left) ||
1227 astHasPointer(tree->right);
1231 /*-----------------------------------------------------------------*/
1232 /* astHasSymbol - return true if the ast has the given symbol */
1233 /*-----------------------------------------------------------------*/
1234 bool astHasSymbol (ast *tree, symbol *sym)
1236 if (!tree || IS_AST_LINK(tree))
1239 if (IS_AST_VALUE(tree)) {
1240 if (IS_AST_SYM_VALUE(tree))
1241 return isSymbolEqual(AST_SYMBOL(tree),sym);
1246 return astHasSymbol(tree->left,sym) ||
1247 astHasSymbol(tree->right,sym);
1250 /*-----------------------------------------------------------------*/
1251 /* isConformingBody - the loop body has to conform to a set of rules */
1252 /* for the loop to be considered reversible read on for rules */
1253 /*-----------------------------------------------------------------*/
1254 bool isConformingBody (ast *pbody, symbol *sym, ast *body)
1257 /* we are going to do a pre-order traversal of the
1258 tree && check for the following conditions. (essentially
1259 a set of very shallow tests )
1260 a) the sym passed does not participate in
1261 any arithmetic operation
1262 b) There are no function calls
1263 c) all jumps are within the body
1264 d) address of loop control variable not taken
1265 e) if an assignment has a pointer on the
1266 left hand side make sure right does not have
1267 loop control variable */
1269 /* if we reach the end or a leaf then true */
1270 if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody))
1274 /* if anything else is "volatile" */
1275 if (IS_VOLATILE(TETYPE(pbody)))
1278 /* we will walk the body in a pre-order traversal for
1280 switch (pbody->opval.op) {
1281 /*------------------------------------------------------------------*/
1283 return isConformingBody (pbody->right,sym,body);
1285 /*------------------------------------------------------------------*/
1290 /*------------------------------------------------------------------*/
1291 case INC_OP: /* incerement operator unary so left only */
1294 /* sure we are not sym is not modified */
1296 IS_AST_SYM_VALUE(pbody->left) &&
1297 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1301 IS_AST_SYM_VALUE(pbody->right) &&
1302 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1307 /*------------------------------------------------------------------*/
1309 case '*' : /* can be unary : if right is null then unary operation */
1314 /* if right is NULL then unary operation */
1315 /*------------------------------------------------------------------*/
1316 /*----------------------------*/
1318 /*----------------------------*/
1319 if ( ! pbody->right ) {
1320 if (IS_AST_SYM_VALUE(pbody->left) &&
1321 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1324 return isConformingBody(pbody->left,sym,body) ;
1326 if (astHasSymbol(pbody->left,sym) ||
1327 astHasSymbol(pbody->right,sym))
1332 /*------------------------------------------------------------------*/
1340 if (IS_AST_SYM_VALUE(pbody->left) &&
1341 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1344 if (IS_AST_SYM_VALUE(pbody->right) &&
1345 isSymbolEqual(AST_SYMBOL(pbody->right),sym))
1348 return isConformingBody(pbody->left,sym,body) &&
1349 isConformingBody(pbody->right,sym,body);
1356 if (IS_AST_SYM_VALUE(pbody->left) &&
1357 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1359 return isConformingBody (pbody->left,sym,body);
1361 /*------------------------------------------------------------------*/
1373 case SIZEOF: /* evaluate wihout code generation */
1375 return isConformingBody(pbody->left,sym,body) &&
1376 isConformingBody(pbody->right,sym,body);
1378 /*------------------------------------------------------------------*/
1381 /* if left has a pointer & right has loop
1382 control variable then we cannot */
1383 if (astHasPointer(pbody->left) &&
1384 astHasSymbol (pbody->right,sym))
1386 if (astHasVolatile(pbody->left))
1389 if (IS_AST_SYM_VALUE(pbody->left) &&
1390 isSymbolEqual(AST_SYMBOL(pbody->left),sym))
1393 if (astHasVolatile(pbody->left))
1396 return isConformingBody(pbody->left,sym,body) &&
1397 isConformingBody(pbody->right,sym,body);
1408 assert("Parser should not have generated this\n");
1410 /*------------------------------------------------------------------*/
1411 /*----------------------------*/
1412 /* comma operator */
1413 /*----------------------------*/
1415 return isConformingBody(pbody->left,sym,body) &&
1416 isConformingBody(pbody->right,sym,body);
1418 /*------------------------------------------------------------------*/
1419 /*----------------------------*/
1421 /*----------------------------*/
1425 /*------------------------------------------------------------------*/
1426 /*----------------------------*/
1427 /* return statement */
1428 /*----------------------------*/
1433 if (isLabelInAst (AST_SYMBOL(pbody->left),body))
1438 if (astHasSymbol(pbody->left,sym))
1445 return isConformingBody(pbody->left,sym,body) &&
1446 isConformingBody(pbody->right,sym,body);
1452 /*-----------------------------------------------------------------*/
1453 /* isLoopReversible - takes a for loop as input && returns true */
1454 /* if the for loop is reversible. If yes will set the value of */
1455 /* the loop control var & init value & termination value */
1456 /*-----------------------------------------------------------------*/
1457 bool isLoopReversible (ast *loop, symbol **loopCntrl,
1458 ast **init, ast **end )
1460 /* if option says don't do it then don't */
1461 if (optimize.noLoopReverse)
1463 /* there are several tests to determine this */
1465 /* for loop has to be of the form
1466 for ( <sym> = <const1> ;
1467 [<sym> < <const2>] ;
1468 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1470 if (! isLoopCountable (AST_FOR(loop,initExpr),
1471 AST_FOR(loop,condExpr),
1472 AST_FOR(loop,loopExpr),
1473 loopCntrl,init,end))
1476 /* now do some serious checking on the body of the loop
1479 return isConformingBody(loop->left,*loopCntrl,loop->left);
1483 /*-----------------------------------------------------------------*/
1484 /* replLoopSym - replace the loop sym by loop sym -1 */
1485 /*-----------------------------------------------------------------*/
1486 static void replLoopSym ( ast *body, symbol *sym)
1489 if (!body || IS_AST_LINK(body))
1492 if (IS_AST_SYM_VALUE(body)) {
1494 if (isSymbolEqual(AST_SYMBOL(body),sym)) {
1497 body->opval.op = '-';
1498 body->left = newAst_VALUE(symbolVal(sym));
1499 body->right= newAst_VALUE(constVal("1"));
1507 replLoopSym(body->left,sym);
1508 replLoopSym(body->right,sym);
1512 /*-----------------------------------------------------------------*/
1513 /* reverseLoop - do the actual loop reversal */
1514 /*-----------------------------------------------------------------*/
1515 ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end)
1519 /* create the following tree
1524 if (sym) goto for_continue ;
1527 /* put it together piece by piece */
1528 rloop = newNode (NULLOP,
1529 createIf(newAst_VALUE(symbolVal(sym)),
1531 newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))),
1534 newAst_VALUE(symbolVal(sym)),
1537 replLoopSym(loop->left, sym);
1539 rloop = newNode(NULLOP,
1541 newAst_VALUE(symbolVal(sym)),
1542 newNode('-',end,init)),
1543 createLabel(AST_FOR(loop,continueLabel),
1548 newAst_VALUE(symbolVal(sym)),
1549 newAst_VALUE(constVal("1"))),
1552 return decorateType(rloop);
1556 #define DEMAND_INTEGER_PROMOTION
1558 #ifdef DEMAND_INTEGER_PROMOTION
1560 /*-----------------------------------------------------------------*/
1561 /* walk a tree looking for the leaves. Add a typecast to the given */
1562 /* type to each value leaf node. */
1563 /*-----------------------------------------------------------------*/
1564 void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr)
1568 /* WTF? We should never get here. */
1572 if (!node->left && !node->right)
1574 /* We're at a leaf; if it's a value, apply the typecast */
1575 if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node)))
1577 *parentPtr = decorateType(newNode(CAST,
1578 newAst_LINK(copyLinkChain(type)),
1586 pushTypeCastToLeaves(type, node->left, &(node->left));
1590 pushTypeCastToLeaves(type, node->right, &(node->right));
1597 /*-----------------------------------------------------------------*/
1598 /* Given an assignment operation in a tree, determine if the LHS */
1599 /* (the result) has a different (integer) type than the RHS. */
1600 /* If so, walk the RHS and add a typecast to the type of the LHS */
1601 /* to all leaf nodes. */
1602 /*-----------------------------------------------------------------*/
1603 void propAsgType(ast *tree)
1605 #ifdef DEMAND_INTEGER_PROMOTION
1606 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree)))
1608 /* Nothing to do here... */
1612 if (getSize(LTYPE(tree)) > getSize(RTYPE(tree)))
1614 pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right));
1621 /*-----------------------------------------------------------------*/
1622 /* decorateType - compute type for this tree also does type cheking*/
1623 /* this is done bottom up, since type have to flow upwards*/
1624 /* it also does constant folding, and paramater checking */
1625 /*-----------------------------------------------------------------*/
1626 ast *decorateType (ast *tree)
1634 /* if already has type then do nothing */
1635 if ( tree->decorated )
1638 tree->decorated = 1;
1640 /* print the line */
1641 /* if not block & function */
1642 if ( tree->type == EX_OP &&
1643 ( tree->opval.op != FUNCTION &&
1644 tree->opval.op != BLOCK &&
1645 tree->opval.op != NULLOP )) {
1646 filename = tree->filename ;
1647 lineno = tree->lineno ;
1650 /* if any child is an error | this one is an error do nothing */
1651 if ( tree->isError ||
1652 ( tree->left && tree->left->isError) ||
1653 ( tree->right && tree->right->isError ))
1656 /*------------------------------------------------------------------*/
1657 /*----------------------------*/
1658 /* leaf has been reached */
1659 /*----------------------------*/
1660 /* if this is of type value */
1661 /* just get the type */
1662 if ( tree->type == EX_VALUE ) {
1664 if ( IS_LITERAL(tree->opval.val->etype) ) {
1666 /* if this is a character array then declare it */
1667 if (IS_ARRAY(tree->opval.val->type))
1668 tree->opval.val = stringToSymbol(tree->opval.val);
1670 /* otherwise just copy the type information */
1671 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1672 if (funcInChain(tree->opval.val->type)) {
1673 tree->hasVargs = tree->opval.val->sym->hasVargs;
1674 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1679 if ( tree->opval.val->sym ) {
1680 /* if the undefined flag is set then give error message */
1681 if (tree->opval.val->sym->undefined ) {
1682 werror(E_ID_UNDEF,tree->opval.val->sym->name) ;
1684 TTYPE(tree) = TETYPE(tree) =
1685 tree->opval.val->type = tree->opval.val->sym->type =
1686 tree->opval.val->etype = tree->opval.val->sym->etype =
1687 copyLinkChain(INTTYPE);
1691 /* if impilicit i.e. struct/union member then no type */
1692 if (tree->opval.val->sym->implicit )
1693 TTYPE(tree) = TETYPE(tree) = NULL ;
1697 /* else copy the type */
1698 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type);
1700 /* and mark it as referenced */
1701 tree->opval.val->sym->isref = 1;
1702 /* if this is of type function or function pointer */
1703 if (funcInChain(tree->opval.val->type)) {
1704 tree->hasVargs = tree->opval.val->sym->hasVargs;
1705 tree->args = copyValueChain(tree->opval.val->sym->args) ;
1715 /* if type link for the case of cast */
1716 if ( tree->type == EX_LINK ) {
1717 COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk);
1724 dtl = decorateType (tree->left);
1725 dtr = decorateType (tree->right);
1727 /* this is to take care of situations
1728 when the tree gets rewritten */
1729 if (dtl != tree->left)
1731 if (dtr != tree->right)
1735 /* depending on type of operator do */
1737 switch (tree->opval.op) {
1738 /*------------------------------------------------------------------*/
1739 /*----------------------------*/
1741 /*----------------------------*/
1744 /* determine which is the array & which the index */
1745 if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) {
1747 ast *tempTree = tree->left ;
1748 tree->left = tree->right ;
1749 tree->right= tempTree ;
1752 /* first check if this is a array or a pointer */
1753 if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) {
1754 werror(E_NEED_ARRAY_PTR,"[]");
1755 goto errorTreeReturn ;
1758 /* check if the type of the idx */
1759 if (!IS_INTEGRAL(RTYPE(tree))) {
1760 werror(E_IDX_NOT_INT);
1761 goto errorTreeReturn ;
1764 /* if the left is an rvalue then error */
1766 werror(E_LVALUE_REQUIRED,"array access");
1767 goto errorTreeReturn ;
1770 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next);
1773 /*------------------------------------------------------------------*/
1774 /*----------------------------*/
1776 /*----------------------------*/
1778 /* if this is not a structure */
1779 if (!IS_STRUCT(LTYPE(tree))) {
1780 werror(E_STRUCT_UNION,".");
1781 goto errorTreeReturn ;
1783 TTYPE(tree) = structElemType (LTYPE(tree),
1784 (tree->right->type == EX_VALUE ?
1785 tree->right->opval.val : NULL ),&tree->args);
1786 TETYPE(tree) = getSpec(TTYPE(tree));
1789 /*------------------------------------------------------------------*/
1790 /*----------------------------*/
1791 /* struct/union pointer */
1792 /*----------------------------*/
1794 /* if not pointer to a structure */
1795 if (!IS_PTR(LTYPE(tree))) {
1797 goto errorTreeReturn ;
1800 if (!IS_STRUCT(LTYPE(tree)->next)) {
1801 werror(E_STRUCT_UNION,"->");
1802 goto errorTreeReturn ;
1805 TTYPE(tree) = structElemType (LTYPE(tree)->next,
1806 (tree->right->type == EX_VALUE ?
1807 tree->right->opval.val : NULL ),&tree->args);
1808 TETYPE(tree) = getSpec(TTYPE(tree));
1811 /*------------------------------------------------------------------*/
1812 /*----------------------------*/
1813 /* ++/-- operation */
1814 /*----------------------------*/
1815 case INC_OP: /* incerement operator unary so left only */
1818 sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) );
1819 COPYTYPE(TTYPE(tree),TETYPE(tree),ltc);
1820 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1821 werror(E_CODE_WRITE,"++/--");
1830 /*------------------------------------------------------------------*/
1831 /*----------------------------*/
1833 /*----------------------------*/
1834 case '&': /* can be unary */
1835 /* if right is NULL then unary operation */
1836 if ( tree->right ) /* not an unary operation */ {
1838 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1839 werror(E_BITWISE_OP);
1840 werror(E_CONTINUE,"left & right types are ");
1841 printTypeChain(LTYPE(tree),stderr);
1842 fprintf(stderr,",");
1843 printTypeChain(RTYPE(tree),stderr);
1844 fprintf(stderr,"\n");
1845 goto errorTreeReturn ;
1848 /* if they are both literal */
1849 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1850 tree->type = EX_VALUE ;
1851 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1852 valFromType(RETYPE(tree)),'&');
1854 tree->right = tree->left = NULL;
1855 TETYPE(tree) = tree->opval.val->etype ;
1856 TTYPE(tree) = tree->opval.val->type;
1860 /* see if this is a GETHBIT operation if yes
1863 ast *otree = optimizeGetHbit(tree);
1866 return decorateType(otree);
1869 /* if right or left is literal then result of that type*/
1870 if (IS_LITERAL(RTYPE(tree))) {
1872 TTYPE(tree) = copyLinkChain(RTYPE(tree));
1873 TETYPE(tree) = getSpec(TTYPE(tree));
1874 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1877 if (IS_LITERAL(LTYPE(tree))) {
1878 TTYPE(tree) = copyLinkChain(LTYPE(tree));
1879 TETYPE(tree) = getSpec(TTYPE(tree));
1880 SPEC_SCLS(TETYPE(tree)) = S_AUTO;
1885 computeType (LTYPE(tree), RTYPE(tree));
1886 TETYPE(tree) = getSpec(TTYPE(tree));
1889 LRVAL(tree) = RRVAL(tree) = 1;
1893 /*------------------------------------------------------------------*/
1894 /*----------------------------*/
1896 /*----------------------------*/
1898 p->class = DECLARATOR;
1899 /* if bit field then error */
1900 if (IS_BITVAR(tree->left->etype)) {
1901 werror (E_ILLEGAL_ADDR,"addrress of bit variable");
1902 goto errorTreeReturn ;
1905 if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) {
1906 werror (E_ILLEGAL_ADDR,"address of register variable");
1907 goto errorTreeReturn;
1910 if (IS_FUNC(LTYPE(tree))) {
1911 werror(E_ILLEGAL_ADDR,"address of function");
1912 goto errorTreeReturn ;
1916 werror(E_LVALUE_REQUIRED,"address of");
1917 goto errorTreeReturn ;
1919 if (SPEC_SCLS(tree->left->etype) == S_CODE) {
1920 DCL_TYPE(p) = CPOINTER ;
1921 DCL_PTR_CONST(p) = port->mem.code_ro;
1924 if (SPEC_SCLS(tree->left->etype) == S_XDATA)
1925 DCL_TYPE(p) = FPOINTER;
1927 if (SPEC_SCLS(tree->left->etype) == S_XSTACK )
1928 DCL_TYPE(p) = PPOINTER ;
1930 if (SPEC_SCLS(tree->left->etype) == S_IDATA)
1931 DCL_TYPE(p) = IPOINTER ;
1933 if (SPEC_SCLS(tree->left->etype) == S_EEPROM)
1934 DCL_TYPE(p) = EEPPOINTER ;
1936 DCL_TYPE(p) = POINTER ;
1938 if (IS_AST_SYM_VALUE(tree->left)) {
1939 AST_SYMBOL(tree->left)->addrtaken = 1;
1940 AST_SYMBOL(tree->left)->allocreq = 1;
1943 p->next = LTYPE(tree);
1945 TETYPE(tree) = getSpec(TTYPE(tree));
1946 DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree));
1947 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree));
1952 /*------------------------------------------------------------------*/
1953 /*----------------------------*/
1955 /*----------------------------*/
1957 /* if the rewrite succeeds then don't go any furthur */
1959 ast *wtree = optimizeRRCRLC ( tree );
1961 return decorateType(wtree) ;
1963 /*------------------------------------------------------------------*/
1964 /*----------------------------*/
1966 /*----------------------------*/
1968 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
1969 werror(E_BITWISE_OP);
1970 werror(E_CONTINUE,"left & right types are ");
1971 printTypeChain(LTYPE(tree),stderr);
1972 fprintf(stderr,",");
1973 printTypeChain(RTYPE(tree),stderr);
1974 fprintf(stderr,"\n");
1975 goto errorTreeReturn ;
1978 /* if they are both literal then */
1979 /* rewrite the tree */
1980 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
1981 tree->type = EX_VALUE ;
1982 tree->opval.val = valBitwise (valFromType(LETYPE(tree)),
1983 valFromType(RETYPE(tree)),
1985 tree->right = tree->left = NULL;
1986 TETYPE(tree) = tree->opval.val->etype;
1987 TTYPE(tree) = tree->opval.val->type;
1990 LRVAL(tree) = RRVAL(tree) = 1;
1991 TETYPE(tree) = getSpec (TTYPE(tree) =
1992 computeType(LTYPE(tree),
1995 /*------------------------------------------------------------------*/
1996 /*----------------------------*/
1998 /*----------------------------*/
2000 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2001 werror(E_INVALID_OP,"divide");
2002 goto errorTreeReturn ;
2004 /* if they are both literal then */
2005 /* rewrite the tree */
2006 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2007 tree->type = EX_VALUE ;
2008 tree->opval.val = valDiv (valFromType(LETYPE(tree)),
2009 valFromType(RETYPE(tree)));
2010 tree->right = tree->left = NULL;
2011 TETYPE(tree) = getSpec(TTYPE(tree) =
2012 tree->opval.val->type);
2015 LRVAL(tree) = RRVAL(tree) = 1;
2016 TETYPE(tree) = getSpec (TTYPE(tree) =
2017 computeType(LTYPE(tree),
2021 /*------------------------------------------------------------------*/
2022 /*----------------------------*/
2024 /*----------------------------*/
2026 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) {
2027 werror(E_BITWISE_OP);
2028 werror(E_CONTINUE,"left & right types are ");
2029 printTypeChain(LTYPE(tree),stderr);
2030 fprintf(stderr,",");
2031 printTypeChain(RTYPE(tree),stderr);
2032 fprintf(stderr,"\n");
2033 goto errorTreeReturn ;
2035 /* if they are both literal then */
2036 /* rewrite the tree */
2037 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2038 tree->type = EX_VALUE ;
2039 tree->opval.val = valMod (valFromType(LETYPE(tree)),
2040 valFromType(RETYPE(tree)));
2041 tree->right = tree->left = NULL;
2042 TETYPE(tree) = getSpec(TTYPE(tree) =
2043 tree->opval.val->type);
2046 LRVAL(tree) = RRVAL(tree) = 1;
2047 TETYPE(tree) = getSpec (TTYPE(tree) =
2048 computeType(LTYPE(tree),
2052 /*------------------------------------------------------------------*/
2053 /*----------------------------*/
2054 /* address dereference */
2055 /*----------------------------*/
2056 case '*': /* can be unary : if right is null then unary operation */
2057 if ( ! tree->right ) {
2058 if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2060 goto errorTreeReturn ;
2064 werror(E_LVALUE_REQUIRED,"pointer deref");
2065 goto errorTreeReturn ;
2067 TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ?
2068 LTYPE(tree)->next : NULL );
2069 TETYPE(tree) = getSpec(TTYPE(tree));
2070 tree->args = tree->left->args ;
2071 tree->hasVargs = tree->left->hasVargs ;
2072 SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree));
2076 /*------------------------------------------------------------------*/
2077 /*----------------------------*/
2078 /* multiplication */
2079 /*----------------------------*/
2080 if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) {
2081 werror(E_INVALID_OP,"multiplication");
2082 goto errorTreeReturn ;
2085 /* if they are both literal then */
2086 /* rewrite the tree */
2087 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2088 tree->type = EX_VALUE ;
2089 tree->opval.val = valMult (valFromType(LETYPE(tree)),
2090 valFromType(RETYPE(tree)));
2091 tree->right = tree->left = NULL;
2092 TETYPE(tree) = getSpec(TTYPE(tree) =
2093 tree->opval.val->type);
2097 /* if left is a literal exchange left & right */
2098 if (IS_LITERAL(LTYPE(tree))) {
2099 ast *tTree = tree->left ;
2100 tree->left = tree->right ;
2101 tree->right= tTree ;
2104 LRVAL(tree) = RRVAL(tree) = 1;
2105 TETYPE(tree) = getSpec (TTYPE(tree) =
2106 computeType(LTYPE(tree),
2110 /*------------------------------------------------------------------*/
2111 /*----------------------------*/
2112 /* unary '+' operator */
2113 /*----------------------------*/
2116 if ( ! tree->right ) {
2117 if (!IS_INTEGRAL(LTYPE(tree))) {
2118 werror(E_UNARY_OP,'+');
2119 goto errorTreeReturn ;
2122 /* if left is a literal then do it */
2123 if (IS_LITERAL(LTYPE(tree))) {
2124 tree->type = EX_VALUE ;
2125 tree->opval.val = valFromType(LETYPE(tree));
2127 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2131 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2135 /*------------------------------------------------------------------*/
2136 /*----------------------------*/
2138 /*----------------------------*/
2140 /* this is not a unary operation */
2141 /* if both pointers then problem */
2142 if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2143 (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) {
2144 werror(E_PTR_PLUS_PTR);
2145 goto errorTreeReturn ;
2148 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2149 !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) {
2150 werror(E_PLUS_INVALID,"+");
2151 goto errorTreeReturn ;
2154 if (!IS_ARITHMETIC(RTYPE(tree)) &&
2155 !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) {
2156 werror(E_PLUS_INVALID,"+");
2157 goto errorTreeReturn;
2159 /* if they are both literal then */
2160 /* rewrite the tree */
2161 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2162 tree->type = EX_VALUE ;
2163 tree->opval.val = valPlus (valFromType(LETYPE(tree)),
2164 valFromType(RETYPE(tree)));
2165 tree->right = tree->left = NULL;
2166 TETYPE(tree) = getSpec(TTYPE(tree) =
2167 tree->opval.val->type);
2171 /* if the right is a pointer or left is a literal
2172 xchange left & right */
2173 if (IS_ARRAY(RTYPE(tree)) ||
2174 IS_PTR(RTYPE(tree)) ||
2175 IS_LITERAL(LTYPE(tree))) {
2176 ast *tTree = tree->left ;
2177 tree->left = tree->right ;
2178 tree->right= tTree ;
2181 LRVAL(tree) = RRVAL(tree) = 1;
2182 /* if the left is a pointer */
2183 if (IS_PTR(LTYPE(tree)))
2184 TETYPE(tree) = getSpec(TTYPE(tree) =
2187 TETYPE(tree) = getSpec(TTYPE(tree) =
2188 computeType(LTYPE(tree),
2192 /*------------------------------------------------------------------*/
2193 /*----------------------------*/
2195 /*----------------------------*/
2196 case '-' : /* can be unary */
2197 /* if right is null then unary */
2198 if ( ! tree->right ) {
2200 if (!IS_ARITHMETIC(LTYPE(tree))) {
2201 werror(E_UNARY_OP,tree->opval.op);
2202 goto errorTreeReturn ;
2205 /* if left is a literal then do it */
2206 if (IS_LITERAL(LTYPE(tree))) {
2207 tree->type = EX_VALUE ;
2208 tree->opval.val = valUnaryPM(valFromType(LETYPE(tree)));
2210 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2214 TTYPE(tree) = LTYPE(tree);
2218 /*------------------------------------------------------------------*/
2219 /*----------------------------*/
2221 /*----------------------------*/
2223 if (!(IS_PTR(LTYPE(tree)) ||
2224 IS_ARRAY(LTYPE(tree)) ||
2225 IS_ARITHMETIC(LTYPE(tree)))) {
2226 werror(E_PLUS_INVALID,"-");
2227 goto errorTreeReturn ;
2230 if (!(IS_PTR(RTYPE(tree)) ||
2231 IS_ARRAY(RTYPE(tree)) ||
2232 IS_ARITHMETIC(RTYPE(tree)))) {
2233 werror(E_PLUS_INVALID,"-");
2234 goto errorTreeReturn ;
2237 if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) &&
2238 ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) ||
2239 IS_INTEGRAL(RTYPE(tree))) ) {
2240 werror(E_PLUS_INVALID,"-");
2241 goto errorTreeReturn ;
2244 /* if they are both literal then */
2245 /* rewrite the tree */
2246 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2247 tree->type = EX_VALUE ;
2248 tree->opval.val = valMinus (valFromType(LETYPE(tree)),
2249 valFromType(RETYPE(tree)));
2250 tree->right = tree->left = NULL;
2251 TETYPE(tree) = getSpec(TTYPE(tree) =
2252 tree->opval.val->type);
2256 /* if the left & right are equal then zero */
2257 if (isAstEqual(tree->left,tree->right)) {
2258 tree->type = EX_VALUE;
2259 tree->left = tree->right = NULL;
2260 tree->opval.val = constVal("0");
2261 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2265 /* if both of them are pointers or arrays then */
2266 /* the result is going to be an integer */
2267 if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) &&
2268 ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))))
2269 TETYPE(tree) = TTYPE(tree) = newIntLink();
2271 /* if only the left is a pointer */
2272 /* then result is a pointer */
2273 if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree)))
2274 TETYPE(tree) = getSpec(TTYPE(tree) =
2277 TETYPE(tree) = getSpec (TTYPE(tree) =
2278 computeType(LTYPE(tree),
2280 LRVAL(tree) = RRVAL(tree) = 1;
2283 /*------------------------------------------------------------------*/
2284 /*----------------------------*/
2286 /*----------------------------*/
2288 /* can be only integral type */
2289 if (!IS_INTEGRAL(LTYPE(tree))) {
2290 werror(E_UNARY_OP,tree->opval.op);
2291 goto errorTreeReturn ;
2294 /* if left is a literal then do it */
2295 if (IS_LITERAL(LTYPE(tree))) {
2296 tree->type = EX_VALUE ;
2297 tree->opval.val = valComplement(valFromType(LETYPE(tree)));
2299 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2303 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2306 /*------------------------------------------------------------------*/
2307 /*----------------------------*/
2309 /*----------------------------*/
2311 /* can be pointer */
2312 if (!IS_ARITHMETIC(LTYPE(tree)) &&
2313 !IS_PTR(LTYPE(tree)) &&
2314 !IS_ARRAY(LTYPE(tree))) {
2315 werror(E_UNARY_OP,tree->opval.op);
2316 goto errorTreeReturn ;
2319 /* if left is a literal then do it */
2320 if (IS_LITERAL(LTYPE(tree))) {
2321 tree->type = EX_VALUE ;
2322 tree->opval.val = valNot(valFromType(LETYPE(tree)));
2324 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2328 TTYPE(tree) = TETYPE(tree) = newCharLink();
2331 /*------------------------------------------------------------------*/
2332 /*----------------------------*/
2334 /*----------------------------*/
2337 TTYPE(tree) = LTYPE(tree);
2338 TETYPE(tree) = LETYPE(tree);
2342 TTYPE(tree) = TETYPE(tree) = newCharLink();
2347 if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) {
2348 werror(E_SHIFT_OP_INVALID);
2349 werror(E_CONTINUE,"left & right types are ");
2350 printTypeChain(LTYPE(tree),stderr);
2351 fprintf(stderr,",");
2352 printTypeChain(RTYPE(tree),stderr);
2353 fprintf(stderr,"\n");
2354 goto errorTreeReturn ;
2357 /* if they are both literal then */
2358 /* rewrite the tree */
2359 if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) {
2360 tree->type = EX_VALUE ;
2361 tree->opval.val = valShift (valFromType(LETYPE(tree)),
2362 valFromType(RETYPE(tree)),
2363 (tree->opval.op == LEFT_OP ? 1 : 0));
2364 tree->right = tree->left = NULL;
2365 TETYPE(tree) = getSpec(TTYPE(tree) =
2366 tree->opval.val->type);
2369 /* if only the right side is a literal & we are
2370 shifting more than size of the left operand then zero */
2371 if (IS_LITERAL(RTYPE(tree)) &&
2372 ((int)floatFromVal( valFromType(RETYPE(tree)))) >=
2373 (getSize(LTYPE(tree))*8)) {
2374 werror(W_SHIFT_CHANGED,
2375 (tree->opval.op == LEFT_OP ? "left" : "right"));
2376 tree->type = EX_VALUE;
2377 tree->left = tree->right = NULL;
2378 tree->opval.val = constVal("0");
2379 TETYPE(tree) = TTYPE(tree) = tree->opval.val->type;
2382 LRVAL(tree) = RRVAL(tree) = 1;
2383 if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) {
2384 COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree));
2386 COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree));
2390 /*------------------------------------------------------------------*/
2391 /*----------------------------*/
2393 /*----------------------------*/
2394 case CAST: /* change the type */
2395 /* cannot cast to an aggregate type */
2396 if (IS_AGGREGATE(LTYPE(tree))) {
2397 werror(E_CAST_ILLEGAL);
2398 goto errorTreeReturn ;
2401 /* if the right is a literal replace the tree */
2402 if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2403 tree->type = EX_VALUE ;
2405 valCastLiteral(LTYPE(tree),
2406 floatFromVal(valFromType(RETYPE(tree))));
2409 TTYPE(tree) = tree->opval.val->type;
2410 tree->values.literalFromCast = 1;
2413 TTYPE(tree) = LTYPE(tree);
2417 TETYPE(tree) = getSpec(TTYPE(tree));
2421 /*------------------------------------------------------------------*/
2422 /*----------------------------*/
2423 /* logical &&, || */
2424 /*----------------------------*/
2427 /* each must me arithmetic type or be a pointer */
2428 if (!IS_PTR(LTYPE(tree)) &&
2429 !IS_ARRAY(LTYPE(tree)) &&
2430 !IS_INTEGRAL(LTYPE(tree))) {
2431 werror(E_COMPARE_OP);
2432 goto errorTreeReturn ;
2435 if (!IS_PTR(RTYPE(tree)) &&
2436 !IS_ARRAY(RTYPE(tree)) &&
2437 !IS_INTEGRAL(RTYPE(tree))) {
2438 werror(E_COMPARE_OP);
2439 goto errorTreeReturn ;
2441 /* if they are both literal then */
2442 /* rewrite the tree */
2443 if (IS_LITERAL(RTYPE(tree)) &&
2444 IS_LITERAL(LTYPE(tree))) {
2445 tree->type = EX_VALUE ;
2446 tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)),
2447 valFromType(RETYPE(tree)),
2449 tree->right = tree->left = NULL;
2450 TETYPE(tree) = getSpec(TTYPE(tree) =
2451 tree->opval.val->type);
2454 LRVAL(tree) = RRVAL(tree) = 1;
2455 TTYPE(tree) = TETYPE(tree) = newCharLink();
2458 /*------------------------------------------------------------------*/
2459 /*----------------------------*/
2460 /* comparison operators */
2461 /*----------------------------*/
2469 ast *lt = optimizeCompare(tree);
2475 /* if they are pointers they must be castable */
2476 if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) {
2477 if (checkType(LTYPE(tree),RTYPE(tree)) == 0) {
2478 werror(E_COMPARE_OP);
2479 fprintf(stderr,"comparing type ");
2480 printTypeChain(LTYPE(tree),stderr);
2481 fprintf(stderr,"to type ");
2482 printTypeChain(RTYPE(tree),stderr);
2483 fprintf(stderr,"\n");
2484 goto errorTreeReturn ;
2487 /* else they should be promotable to one another */
2489 if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) ||
2490 ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))))
2492 if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) {
2493 werror(E_COMPARE_OP);
2494 fprintf(stderr,"comparing type ");
2495 printTypeChain(LTYPE(tree),stderr);
2496 fprintf(stderr,"to type ");
2497 printTypeChain(RTYPE(tree),stderr);
2498 fprintf(stderr,"\n");
2499 goto errorTreeReturn ;
2503 /* if they are both literal then */
2504 /* rewrite the tree */
2505 if (IS_LITERAL(RTYPE(tree)) &&
2506 IS_LITERAL(LTYPE(tree))) {
2507 tree->type = EX_VALUE ;
2508 tree->opval.val = valCompare (valFromType(LETYPE(tree)),
2509 valFromType(RETYPE(tree)),
2511 tree->right = tree->left = NULL;
2512 TETYPE(tree) = getSpec(TTYPE(tree) =
2513 tree->opval.val->type);
2516 LRVAL(tree) = RRVAL(tree) = 1;
2517 TTYPE(tree) = TETYPE(tree) = newCharLink();
2520 /*------------------------------------------------------------------*/
2521 /*----------------------------*/
2523 /*----------------------------*/
2524 case SIZEOF : /* evaluate wihout code generation */
2525 /* change the type to a integer */
2526 tree->type = EX_VALUE;
2527 sprintf(buffer,"%d",(getSize(tree->right->ftype)));
2528 tree->opval.val = constVal(buffer);
2529 tree->right = tree->left = NULL;
2530 TETYPE(tree) = getSpec(TTYPE(tree) =
2531 tree->opval.val->type);
2534 /*------------------------------------------------------------------*/
2535 /*----------------------------*/
2536 /* conditional operator '?' */
2537 /*----------------------------*/
2539 /* the type is one on the left */
2540 TTYPE(tree) = LTYPE(tree);
2541 TETYPE(tree)= getSpec (TTYPE(tree));
2545 /* if they don't match we have a problem */
2546 if (checkType( LTYPE(tree), RTYPE(tree)) == 0) {
2547 werror(E_TYPE_MISMATCH,"conditional operator"," ");
2548 goto errorTreeReturn ;
2551 TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree));
2552 TETYPE(tree)= getSpec(TTYPE(tree));
2556 /*------------------------------------------------------------------*/
2557 /*----------------------------*/
2558 /* assignment operators */
2559 /*----------------------------*/
2562 /* for these it must be both must be integral */
2563 if (!IS_ARITHMETIC(LTYPE(tree)) ||
2564 !IS_ARITHMETIC(RTYPE(tree))) {
2565 werror (E_OPS_INTEGRAL);
2566 goto errorTreeReturn ;
2569 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2571 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2572 werror(E_CODE_WRITE," ");
2575 werror(E_LVALUE_REQUIRED,"*= or /=");
2576 goto errorTreeReturn ;
2589 /* for these it must be both must be integral */
2590 if (!IS_INTEGRAL(LTYPE(tree)) ||
2591 !IS_INTEGRAL(RTYPE(tree))) {
2592 werror (E_OPS_INTEGRAL);
2593 goto errorTreeReturn ;
2596 TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree));
2598 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2599 werror(E_CODE_WRITE," ");
2602 werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<=");
2603 goto errorTreeReturn ;
2611 /*------------------------------------------------------------------*/
2612 /*----------------------------*/
2614 /*----------------------------*/
2616 if (!(IS_PTR(LTYPE(tree)) ||
2617 IS_ARITHMETIC(LTYPE(tree)))) {
2618 werror(E_PLUS_INVALID,"-=");
2619 goto errorTreeReturn ;
2622 if (!(IS_PTR(RTYPE(tree)) ||
2623 IS_ARITHMETIC(RTYPE(tree)))) {
2624 werror(E_PLUS_INVALID,"-=");
2625 goto errorTreeReturn ;
2628 TETYPE(tree) = getSpec (TTYPE(tree) =
2629 computeType(LTYPE(tree),
2632 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2633 werror(E_CODE_WRITE," ");
2636 werror(E_LVALUE_REQUIRED,"-=");
2637 goto errorTreeReturn ;
2645 /*------------------------------------------------------------------*/
2646 /*----------------------------*/
2648 /*----------------------------*/
2650 /* this is not a unary operation */
2651 /* if both pointers then problem */
2652 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) {
2653 werror(E_PTR_PLUS_PTR);
2654 goto errorTreeReturn ;
2657 if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) {
2658 werror(E_PLUS_INVALID,"+=");
2659 goto errorTreeReturn ;
2662 if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) {
2663 werror(E_PLUS_INVALID,"+=");
2664 goto errorTreeReturn;
2667 TETYPE(tree) = getSpec (TTYPE(tree) =
2668 computeType(LTYPE(tree),
2671 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2672 werror(E_CODE_WRITE," ");
2675 werror(E_LVALUE_REQUIRED,"+=");
2676 goto errorTreeReturn ;
2679 tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right));
2680 tree->opval.op = '=';
2686 /*------------------------------------------------------------------*/
2687 /*----------------------------*/
2688 /* straight assignemnt */
2689 /*----------------------------*/
2691 /* cannot be an aggregate */
2692 if (IS_AGGREGATE(LTYPE(tree))) {
2693 werror(E_AGGR_ASSIGN);
2694 goto errorTreeReturn;
2697 /* they should either match or be castable */
2698 if (checkType (LTYPE(tree),RTYPE(tree)) == 0) {
2699 werror(E_TYPE_MISMATCH,"assignment"," ");
2700 fprintf(stderr,"type --> '");
2701 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2702 fprintf(stderr,"assigned to type --> '");
2703 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2704 goto errorTreeReturn ;
2707 /* if the left side of the tree is of type void
2708 then report error */
2709 if (IS_VOID(LTYPE(tree))) {
2710 werror(E_CAST_ZERO);
2711 fprintf(stderr,"type --> '");
2712 printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' ");
2713 fprintf(stderr,"assigned to type --> '");
2714 printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n");
2717 /* extra checks for pointer types */
2718 if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) &&
2719 !IS_GENPTR(LTYPE(tree))) {
2720 if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree)))
2721 werror(W_PTR_ASSIGN);
2724 TETYPE(tree) = getSpec(TTYPE(tree) =
2728 if (!tree->initMode && IS_CONSTANT(LETYPE(tree)))
2729 werror(E_CODE_WRITE," ");
2732 werror(E_LVALUE_REQUIRED,"=");
2733 goto errorTreeReturn ;
2740 /*------------------------------------------------------------------*/
2741 /*----------------------------*/
2742 /* comma operator */
2743 /*----------------------------*/
2745 TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree));
2748 /*------------------------------------------------------------------*/
2749 /*----------------------------*/
2751 /*----------------------------*/
2756 if (processParms (tree->left,
2758 tree->right,&parmNumber))
2759 goto errorTreeReturn ;
2761 if (options.stackAuto || IS_RENT(LETYPE(tree))) {
2762 tree->left->args = reverseVal(tree->left->args);
2763 reverseParms(tree->right);
2766 tree->args = tree->left->args ;
2767 TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next);
2770 /*------------------------------------------------------------------*/
2771 /*----------------------------*/
2772 /* return statement */
2773 /*----------------------------*/
2778 if (checkType(currFunc->type->next,RTYPE(tree)) == 0) {
2779 werror(E_RETURN_MISMATCH);
2780 goto errorTreeReturn ;
2783 if (IS_VOID(currFunc->type->next)
2785 !IS_VOID(RTYPE(tree))) {
2786 werror(E_FUNC_VOID);
2787 goto errorTreeReturn ;
2790 /* if there is going to be a casing required then add it */
2791 if (checkType(currFunc->type->next,RTYPE(tree)) < 0 )
2793 #if 0 && defined DEMAND_INTEGER_PROMOTION
2794 if (IS_INTEGRAL(currFunc->type->next))
2796 pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right));
2802 decorateType(newNode(CAST,
2803 newAst_LINK(copyLinkChain(currFunc->type->next)),
2813 if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) {
2814 werror(E_VOID_FUNC,currFunc->name);
2815 goto errorTreeReturn ;
2818 TTYPE(tree) = TETYPE(tree) = NULL ;
2821 /*------------------------------------------------------------------*/
2822 /*----------------------------*/
2823 /* switch statement */
2824 /*----------------------------*/
2826 /* the switch value must be an integer */
2827 if (!IS_INTEGRAL(LTYPE(tree))) {
2828 werror (E_SWITCH_NON_INTEGER);
2829 goto errorTreeReturn ;
2832 TTYPE(tree) = TETYPE(tree) = NULL ;
2835 /*------------------------------------------------------------------*/
2836 /*----------------------------*/
2838 /*----------------------------*/
2840 tree->left = backPatchLabels(tree->left,
2843 TTYPE(tree) = TETYPE(tree) = NULL;
2846 /*------------------------------------------------------------------*/
2847 /*----------------------------*/
2849 /*----------------------------*/
2852 decorateType(resolveSymbols(AST_FOR(tree,initExpr)));
2853 decorateType(resolveSymbols(AST_FOR(tree,condExpr)));
2854 decorateType(resolveSymbols(AST_FOR(tree,loopExpr)));
2856 /* if the for loop is reversible then
2857 reverse it otherwise do what we normally
2863 if (isLoopReversible (tree,&sym,&init,&end))
2864 return reverseLoop (tree,sym,init,end);
2866 return decorateType(createFor ( AST_FOR(tree,trueLabel),
2867 AST_FOR(tree,continueLabel) ,
2868 AST_FOR(tree,falseLabel) ,
2869 AST_FOR(tree,condLabel) ,
2870 AST_FOR(tree,initExpr) ,
2871 AST_FOR(tree,condExpr) ,
2872 AST_FOR(tree,loopExpr),
2876 TTYPE(tree) = TETYPE(tree) = NULL ;
2880 /* some error found this tree will be killed */
2882 TTYPE(tree) = TETYPE(tree) = newCharLink();
2883 tree->opval.op = NULLOP ;
2889 /*-----------------------------------------------------------------*/
2890 /* sizeofOp - processes size of operation */
2891 /*-----------------------------------------------------------------*/
2892 value *sizeofOp( sym_link *type)
2896 /* get the size and convert it to character */
2897 sprintf (buff,"%d", getSize(type));
2899 /* now convert into value */
2900 return constVal (buff);
2904 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
2905 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
2906 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
2907 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
2908 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
2909 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
2910 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
2912 /*-----------------------------------------------------------------*/
2913 /* backPatchLabels - change and or not operators to flow control */
2914 /*-----------------------------------------------------------------*/
2915 ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel )
2921 if ( ! (IS_ANDORNOT(tree)))
2924 /* if this an and */
2926 static int localLbl = 0 ;
2927 symbol *localLabel ;
2929 sprintf (buffer,"_and_%d",localLbl++);
2930 localLabel = newSymbol(buffer,NestLevel);
2932 tree->left = backPatchLabels (tree->left, localLabel,falseLabel);
2934 /* if left is already a IFX then just change the if true label in that */
2935 if (!IS_IFX(tree->left))
2936 tree->left = newIfxNode(tree->left,localLabel,falseLabel);
2938 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2939 /* right is a IFX then just join */
2940 if (IS_IFX(tree->right))
2941 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2943 tree->right = createLabel(localLabel,tree->right);
2944 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2946 return newNode(NULLOP,tree->left,tree->right);
2949 /* if this is an or operation */
2951 static int localLbl = 0 ;
2952 symbol *localLabel ;
2954 sprintf (buffer,"_or_%d",localLbl++);
2955 localLabel = newSymbol(buffer,NestLevel);
2957 tree->left = backPatchLabels (tree->left, trueLabel,localLabel);
2959 /* if left is already a IFX then just change the if true label in that */
2960 if (!IS_IFX(tree->left))
2961 tree->left = newIfxNode(tree->left,trueLabel,localLabel);
2963 tree->right = backPatchLabels(tree->right,trueLabel,falseLabel);
2964 /* right is a IFX then just join */
2965 if (IS_IFX(tree->right))
2966 return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right));
2968 tree->right = createLabel(localLabel,tree->right);
2969 tree->right = newIfxNode(tree->right,trueLabel,falseLabel);
2971 return newNode(NULLOP,tree->left,tree->right);
2976 int wasnot = IS_NOT(tree->left);
2977 tree->left = backPatchLabels (tree->left,falseLabel,trueLabel);
2979 /* if the left is already a IFX */
2980 if ( ! IS_IFX(tree->left) )
2981 tree->left = newNode (IFX,tree->left,NULL);
2984 tree->left->trueLabel = trueLabel ;
2985 tree->left->falseLabel= falseLabel ;
2987 tree->left->trueLabel = falseLabel ;
2988 tree->left->falseLabel= trueLabel ;
2994 tree->trueLabel = trueLabel ;
2995 tree->falseLabel= falseLabel;
3002 /*-----------------------------------------------------------------*/
3003 /* createBlock - create expression tree for block */
3004 /*-----------------------------------------------------------------*/
3005 ast *createBlock ( symbol *decl, ast *body )
3009 /* if the block has nothing */
3013 ex = newNode(BLOCK,NULL,body);
3014 ex->values.sym = decl ;
3016 ex->right = ex->right ;
3022 /*-----------------------------------------------------------------*/
3023 /* createLabel - creates the expression tree for labels */
3024 /*-----------------------------------------------------------------*/
3025 ast *createLabel ( symbol *label, ast *stmnt )
3028 char name[SDCC_NAME_MAX+1];
3031 /* must create fresh symbol if the symbol name */
3032 /* exists in the symbol table, since there can */
3033 /* be a variable with the same name as the labl */
3034 if ((csym = findSym (SymbolTab,NULL,label->name)) &&
3035 (csym->level == label->level))
3036 label = newSymbol(label->name,label->level);
3038 /* change the name before putting it in add _*/
3039 sprintf (name,"%s",label->name);
3041 /* put the label in the LabelSymbol table */
3042 /* but first check if a label of the same */
3044 if ( (csym = findSym(LabelTab,NULL,name)))
3045 werror(E_DUPLICATE_LABEL,label->name);
3047 addSym (LabelTab, label, name,label->level,0);
3050 label->key = labelKey++ ;
3051 rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt);
3057 /*-----------------------------------------------------------------*/
3058 /* createCase - generates the parsetree for a case statement */
3059 /*-----------------------------------------------------------------*/
3060 ast *createCase (ast *swStat, ast *caseVal, ast *stmnt )
3062 char caseLbl[SDCC_NAME_MAX+1];
3066 /* if the switch statement does not exist */
3067 /* then case is out of context */
3069 werror(E_CASE_CONTEXT);
3073 caseVal = decorateType(resolveSymbols(caseVal));
3074 /* if not a constant then error */
3075 if (!IS_LITERAL(caseVal->ftype)) {
3076 werror(E_CASE_CONSTANT);
3080 /* if not a integer than error */
3081 if (!IS_INTEGRAL(caseVal->ftype)) {
3082 werror(E_CASE_NON_INTEGER);
3086 /* find the end of the switch values chain */
3087 if (!(val = swStat->values.switchVals.swVals))
3088 swStat->values.switchVals.swVals = caseVal->opval.val ;
3090 /* also order the cases according to value */
3092 int cVal = (int) floatFromVal(caseVal->opval.val);
3093 while (val && (int) floatFromVal(val) < cVal) {
3098 /* if we reached the end then */
3100 pval->next = caseVal->opval.val;
3102 /* we found a value greater than */
3103 /* the current value we must add this */
3104 /* before the value */
3105 caseVal->opval.val->next = val;
3107 /* if this was the first in chain */
3108 if (swStat->values.switchVals.swVals == val)
3109 swStat->values.switchVals.swVals =
3112 pval->next = caseVal->opval.val;
3117 /* create the case label */
3118 sprintf(caseLbl,"_case_%d_%d",
3119 swStat->values.switchVals.swNum,
3120 (int) floatFromVal(caseVal->opval.val));
3122 rexpr = createLabel(newSymbol(caseLbl,0),stmnt);
3127 /*-----------------------------------------------------------------*/
3128 /* createDefault - creates the parse tree for the default statement*/
3129 /*-----------------------------------------------------------------*/
3130 ast *createDefault (ast *swStat, ast *stmnt)
3132 char defLbl[SDCC_NAME_MAX+1];
3134 /* if the switch statement does not exist */
3135 /* then case is out of context */
3137 werror(E_CASE_CONTEXT);
3141 /* turn on the default flag */
3142 swStat->values.switchVals.swDefault = 1 ;
3144 /* create the label */
3145 sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum);
3146 return createLabel(newSymbol(defLbl,0),stmnt);
3149 /*-----------------------------------------------------------------*/
3150 /* createIf - creates the parsetree for the if statement */
3151 /*-----------------------------------------------------------------*/
3152 ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody )
3154 static int Lblnum = 0 ;
3156 symbol *ifTrue , *ifFalse, *ifEnd ;
3158 /* if neither exists */
3159 if (! elseBody && !ifBody)
3162 /* create the labels */
3163 sprintf (buffer,"_iffalse_%d",Lblnum);
3164 ifFalse = newSymbol (buffer,NestLevel);
3165 /* if no else body then end == false */
3169 sprintf (buffer,"_ifend_%d",Lblnum);
3170 ifEnd = newSymbol (buffer,NestLevel);
3173 sprintf (buffer,"_iftrue_%d",Lblnum);
3174 ifTrue = newSymbol (buffer,NestLevel);
3178 /* attach the ifTrue label to the top of it body */
3179 ifBody = createLabel(ifTrue,ifBody);
3180 /* attach a goto end to the ifBody if else is present */
3182 ifBody = newNode(NULLOP,ifBody,
3184 newAst_VALUE(symbolVal(ifEnd)),
3186 /* put the elseLabel on the else body */
3187 elseBody = createLabel (ifFalse,elseBody);
3188 /* out the end at the end of the body */
3189 elseBody = newNode(NULLOP,
3191 createLabel(ifEnd,NULL));
3194 ifBody = newNode(NULLOP,ifBody,
3195 createLabel(ifFalse,NULL));
3197 condAst = backPatchLabels (condAst,ifTrue,ifFalse);
3198 if (IS_IFX(condAst))
3201 ifTree = newIfxNode(condAst,ifTrue,ifFalse);
3203 return newNode(NULLOP,ifTree,
3204 newNode(NULLOP,ifBody,elseBody));
3208 /*-----------------------------------------------------------------*/
3209 /* createDo - creates parse tree for do */
3212 /* _docontinue_n: */
3213 /* condition_expression +-> trueLabel -> _dobody_n */
3215 /* +-> falseLabel-> _dobreak_n */
3217 /*-----------------------------------------------------------------*/
3218 ast *createDo ( symbol *trueLabel, symbol *continueLabel,
3219 symbol *falseLabel, ast *condAst, ast *doBody )
3224 /* if the body does not exist then it is simple */
3226 condAst = backPatchLabels(condAst,continueLabel,NULL);
3227 doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst)
3228 : newNode(IFX,createLabel(continueLabel,condAst),NULL));
3229 doTree->trueLabel = continueLabel ;
3230 doTree->falseLabel= NULL ;
3234 /* otherwise we have a body */
3235 condAst = backPatchLabels(condAst,trueLabel,falseLabel);
3237 /* attach the body label to the top */
3238 doBody = createLabel(trueLabel,doBody);
3239 /* attach the continue label to end of body */
3240 doBody = newNode(NULLOP, doBody,
3241 createLabel(continueLabel,NULL));
3243 /* now put the break label at the end */
3244 if (IS_IFX(condAst))
3247 doTree = newIfxNode(condAst,trueLabel,falseLabel);
3249 doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL));
3251 /* putting it together */
3252 return newNode(NULLOP,doBody,doTree);
3255 /*-----------------------------------------------------------------*/
3256 /* createFor - creates parse tree for 'for' statement */
3259 /* condExpr +-> trueLabel -> _forbody_n */
3261 /* +-> falseLabel-> _forbreak_n */
3264 /* _forcontinue_n: */
3266 /* goto _forcond_n ; */
3268 /*-----------------------------------------------------------------*/
3269 ast *createFor ( symbol *trueLabel, symbol *continueLabel ,
3270 symbol *falseLabel,symbol *condLabel ,
3271 ast *initExpr, ast *condExpr, ast *loopExpr,
3276 /* if loopexpression not present then we can generate it */
3277 /* the same way as a while */
3279 return newNode(NULLOP,initExpr,
3280 createWhile (trueLabel, continueLabel,
3281 falseLabel,condExpr, forBody ));
3282 /* vanilla for statement */
3283 condExpr = backPatchLabels(condExpr,trueLabel,falseLabel);
3285 if (condExpr && !IS_IFX(condExpr))
3286 condExpr = newIfxNode(condExpr,trueLabel,falseLabel);
3289 /* attach condition label to condition */
3290 condExpr = createLabel(condLabel,condExpr);
3292 /* attach body label to body */
3293 forBody = createLabel(trueLabel,forBody);
3295 /* attach continue to forLoop expression & attach */
3296 /* goto the forcond @ and of loopExpression */
3297 loopExpr = createLabel(continueLabel,
3301 newAst_VALUE(symbolVal(condLabel)),
3303 /* now start putting them together */
3304 forTree = newNode(NULLOP,initExpr,condExpr);
3305 forTree = newNode(NULLOP,forTree,forBody);
3306 forTree = newNode(NULLOP,forTree,loopExpr);
3307 /* finally add the break label */
3308 forTree = newNode(NULLOP,forTree,
3309 createLabel(falseLabel,NULL));
3313 /*-----------------------------------------------------------------*/
3314 /* createWhile - creates parse tree for while statement */
3315 /* the while statement will be created as follows */
3317 /* _while_continue_n: */
3318 /* condition_expression +-> trueLabel -> _while_boby_n */
3320 /* +-> falseLabel -> _while_break_n*/
3321 /* _while_body_n: */
3323 /* goto _while_continue_n */
3324 /* _while_break_n: */
3325 /*-----------------------------------------------------------------*/
3326 ast *createWhile (symbol *trueLabel, symbol *continueLabel,
3327 symbol *falseLabel,ast *condExpr, ast *whileBody )
3331 /* put the continue label */
3332 condExpr = backPatchLabels (condExpr,trueLabel,falseLabel);
3333 condExpr = createLabel(continueLabel,condExpr);
3334 condExpr->lineno = 0;
3336 /* put the body label in front of the body */
3337 whileBody = createLabel(trueLabel,whileBody);
3338 whileBody->lineno = 0;
3339 /* put a jump to continue at the end of the body */
3340 /* and put break label at the end of the body */
3341 whileBody = newNode(NULLOP,
3344 newAst_VALUE(symbolVal(continueLabel)),
3345 createLabel(falseLabel,NULL)));
3347 /* put it all together */
3348 if ( IS_IFX(condExpr) )
3349 whileTree = condExpr ;
3351 whileTree = newNode (IFX, condExpr,NULL );
3352 /* put the true & false labels in place */
3353 whileTree->trueLabel = trueLabel ;
3354 whileTree->falseLabel= falseLabel;
3357 return newNode(NULLOP,whileTree,whileBody );
3360 /*-----------------------------------------------------------------*/
3361 /* optimizeGetHbit - get highest order bit of the expression */
3362 /*-----------------------------------------------------------------*/
3363 ast *optimizeGetHbit (ast *tree)
3366 /* if this is not a bit and */
3367 if (!IS_BITAND(tree))
3370 /* will look for tree of the form
3371 ( expr >> ((sizeof expr) -1) ) & 1 */
3372 if (!IS_AST_LIT_VALUE(tree->right))
3375 if (AST_LIT_VALUE(tree->right) != 1)
3378 if (!IS_RIGHT_OP(tree->left))
3381 if (!IS_AST_LIT_VALUE(tree->left->right))
3384 if ((i = AST_LIT_VALUE(tree->left->right)) !=
3385 ( j = (getSize(TTYPE(tree->left->left))*8 - 1)))
3388 return decorateType(newNode(GETHBIT,tree->left->left,NULL));
3392 /*-----------------------------------------------------------------*/
3393 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3394 /*-----------------------------------------------------------------*/
3395 ast *optimizeRRCRLC ( ast *root )
3397 /* will look for trees of the form
3398 (?expr << 1) | (?expr >> 7) or
3399 (?expr >> 7) | (?expr << 1) will make that
3400 into a RLC : operation ..
3402 (?expr >> 1) | (?expr << 7) or
3403 (?expr << 7) | (?expr >> 1) will make that
3404 into a RRC operation
3405 note : by 7 I mean (number of bits required to hold the
3407 /* if the root operations is not a | operation the not */
3408 if (!IS_BITOR(root))
3411 /* I have to think of a better way to match patterns this sucks */
3412 /* that aside let start looking for the first case : I use a the
3413 negative check a lot to improve the efficiency */
3414 /* (?expr << 1) | (?expr >> 7) */
3415 if (IS_LEFT_OP(root->left) &&
3416 IS_RIGHT_OP(root->right) ) {
3418 if (!SPEC_USIGN(TETYPE(root->left->left)))
3421 if (!IS_AST_LIT_VALUE(root->left->right) ||
3422 !IS_AST_LIT_VALUE(root->right->right))
3425 /* make sure it is the same expression */
3426 if (!isAstEqual(root->left->left,
3430 if (AST_LIT_VALUE(root->left->right) != 1 )
3433 if (AST_LIT_VALUE(root->right->right) !=
3434 (getSize(TTYPE(root->left->left))*8 - 1))
3437 /* whew got the first case : create the AST */
3438 return newNode(RLC,root->left->left,NULL);
3442 /* check for second case */
3443 /* (?expr >> 7) | (?expr << 1) */
3444 if (IS_LEFT_OP(root->right) &&
3445 IS_RIGHT_OP(root->left) ) {
3447 if (!SPEC_USIGN(TETYPE(root->left->left)))
3450 if (!IS_AST_LIT_VALUE(root->left->right) ||
3451 !IS_AST_LIT_VALUE(root->right->right))
3454 /* make sure it is the same symbol */
3455 if (!isAstEqual(root->left->left,
3459 if (AST_LIT_VALUE(root->right->right) != 1 )
3462 if (AST_LIT_VALUE(root->left->right) !=
3463 (getSize(TTYPE(root->left->left))*8 - 1))
3466 /* whew got the first case : create the AST */
3467 return newNode(RLC,root->left->left,NULL);
3472 /* third case for RRC */
3473 /* (?symbol >> 1) | (?symbol << 7) */
3474 if (IS_LEFT_OP(root->right) &&
3475 IS_RIGHT_OP(root->left) ) {
3477 if (!SPEC_USIGN(TETYPE(root->left->left)))
3480 if (!IS_AST_LIT_VALUE(root->left->right) ||
3481 !IS_AST_LIT_VALUE(root->right->right))
3484 /* make sure it is the same symbol */
3485 if (!isAstEqual(root->left->left,
3489 if (AST_LIT_VALUE(root->left->right) != 1 )
3492 if (AST_LIT_VALUE(root->right->right) !=
3493 (getSize(TTYPE(root->left->left))*8 - 1))
3496 /* whew got the first case : create the AST */
3497 return newNode(RRC,root->left->left,NULL);
3501 /* fourth and last case for now */
3502 /* (?symbol << 7) | (?symbol >> 1) */
3503 if (IS_RIGHT_OP(root->right) &&
3504 IS_LEFT_OP(root->left) ) {
3506 if (!SPEC_USIGN(TETYPE(root->left->left)))
3509 if (!IS_AST_LIT_VALUE(root->left->right) ||
3510 !IS_AST_LIT_VALUE(root->right->right))
3513 /* make sure it is the same symbol */
3514 if (!isAstEqual(root->left->left,
3518 if (AST_LIT_VALUE(root->right->right) != 1 )
3521 if (AST_LIT_VALUE(root->left->right) !=
3522 (getSize(TTYPE(root->left->left))*8 - 1))
3525 /* whew got the first case : create the AST */
3526 return newNode(RRC,root->left->left,NULL);
3530 /* not found return root */
3534 /*-----------------------------------------------------------------*/
3535 /* optimizeCompare - otimizes compares for bit variables */
3536 /*-----------------------------------------------------------------*/
3537 ast *optimizeCompare ( ast *root )
3539 ast *optExpr = NULL;
3542 unsigned int litValue ;
3544 /* if nothing then return nothing */
3548 /* if not a compare op then do leaves */
3549 if (!IS_COMPARE_OP(root)) {
3550 root->left = optimizeCompare (root->left);
3551 root->right= optimizeCompare (root->right);
3555 /* if left & right are the same then depending
3556 of the operation do */
3557 if (isAstEqual(root->left,root->right)) {
3558 switch (root->opval.op) {
3562 optExpr = newAst_VALUE(constVal("0"));
3567 optExpr = newAst_VALUE(constVal("1"));
3571 return decorateType(optExpr);
3574 vleft = (root->left->type == EX_VALUE ?
3575 root->left->opval.val : NULL );
3577 vright = (root->right->type == EX_VALUE ?
3578 root->right->opval.val : NULL);
3580 /* if left is a BITVAR in BITSPACE */
3581 /* and right is a LITERAL then opt-*/
3582 /* imize else do nothing */
3583 if (vleft && vright &&
3584 IS_BITVAR(vleft->etype) &&
3585 IN_BITSPACE(SPEC_OCLS(vleft->etype)) &&
3586 IS_LITERAL(vright->etype)) {
3588 /* if right side > 1 then comparison may never succeed */
3589 if ( (litValue = (int) floatFromVal(vright)) > 1 ) {
3590 werror(W_BAD_COMPARE);
3595 switch (root->opval.op) {
3596 case '>' : /* bit value greater than 1 cannot be */
3597 werror(W_BAD_COMPARE);
3601 case '<' : /* bit value < 1 means 0 */
3603 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3606 case LE_OP : /* bit value <= 1 means no check */
3607 optExpr = newAst_VALUE(vright);
3610 case GE_OP : /* bit value >= 1 means only check for = */
3612 optExpr = newAst_VALUE(vleft);
3615 } else { /* literal is zero */
3616 switch (root->opval.op) {
3617 case '<' : /* bit value < 0 cannot be */
3618 werror(W_BAD_COMPARE);
3622 case '>' : /* bit value > 0 means 1 */
3624 optExpr = newAst_VALUE(vleft);
3627 case LE_OP : /* bit value <= 0 means no check */
3628 case GE_OP : /* bit value >= 0 means no check */
3629 werror(W_BAD_COMPARE);
3633 case EQ_OP : /* bit == 0 means ! of bit */
3634 optExpr = newNode('!',newAst_VALUE(vleft),NULL);
3638 return decorateType(resolveSymbols(optExpr));
3639 } /* end-of-if of BITVAR */
3644 /*-----------------------------------------------------------------*/
3645 /* addSymToBlock : adds the symbol to the first block we find */
3646 /*-----------------------------------------------------------------*/
3647 void addSymToBlock (symbol *sym, ast *tree)
3649 /* reached end of tree or a leaf */
3650 if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree))
3654 if (IS_AST_OP(tree) &&
3655 tree->opval.op == BLOCK ) {
3657 symbol *lsym = copySymbol(sym);
3659 lsym->next = AST_VALUES(tree,sym);
3660 AST_VALUES(tree,sym) = lsym ;
3664 addSymToBlock(sym,tree->left);
3665 addSymToBlock(sym,tree->right);
3668 /*-----------------------------------------------------------------*/
3669 /* processRegParms - do processing for register parameters */
3670 /*-----------------------------------------------------------------*/
3671 static void processRegParms (value *args, ast *body)
3674 if (IS_REGPARM(args->etype))
3675 addSymToBlock(args->sym,body);
3680 /*-----------------------------------------------------------------*/
3681 /* resetParmKey - resets the operandkeys for the symbols */
3682 /*-----------------------------------------------------------------*/
3683 DEFSETFUNC(resetParmKey)
3694 /*-----------------------------------------------------------------*/
3695 /* createFunction - This is the key node that calls the iCode for */
3696 /* generating the code for a function. Note code */
3697 /* is generated function by function, later when */
3698 /* add inter-procedural analysis this will change */
3699 /*-----------------------------------------------------------------*/
3700 ast *createFunction (symbol *name, ast *body )
3706 iCode *piCode = NULL;
3708 /* if check function return 0 then some problem */
3709 if (checkFunction (name) == 0)
3712 /* create a dummy block if none exists */
3714 body = newNode(BLOCK,NULL,NULL);
3718 /* check if the function name already in the symbol table */
3719 if ((csym = findSym (SymbolTab,NULL,name->name))) {
3721 /* special case for compiler defined functions
3722 we need to add the name to the publics list : this
3723 actually means we are now compiling the compiler
3726 addSet(&publics,name);
3731 allocVariables(name);
3733 name->lastLine = yylineno;
3735 processFuncArgs(currFunc,0);
3737 /* set the stack pointer */
3738 /* PENDING: check this for the mcs51 */
3739 stackPtr = -port->stack.direction * port->stack.call_overhead;
3740 if (IS_ISR(name->etype))
3741 stackPtr -= port->stack.direction * port->stack.isr_overhead;
3742 if (IS_RENT(name->etype) || options.stackAuto)
3743 stackPtr -= port->stack.direction * port->stack.reent_overhead;
3745 xstackPtr = -port->stack.direction * port->stack.call_overhead;
3747 fetype = getSpec(name->type); /* get the specifier for the function */
3748 /* if this is a reentrant function then */
3749 if (IS_RENT(fetype))
3752 allocParms (name->args); /* allocate the parameters */
3754 /* do processing for parameters that are passed in registers */
3755 processRegParms (name->args,body);
3757 /* set the stack pointer */
3761 /* allocate & autoinit the block variables */
3762 processBlockVars (body, &stack,ALLOCATE);
3764 /* save the stack information */
3765 if (options.useXstack)
3766 name->xstack = SPEC_STAK(fetype) = stack;
3768 name->stack = SPEC_STAK(fetype) = stack;
3770 /* name needs to be mangled */
3771 sprintf (name->rname,"%s%s", port->fun_prefix, name->name);
3773 body = resolveSymbols(body); /* resolve the symbols */
3774 body = decorateType (body); /* propagateType & do semantic checks */
3776 ex = newAst_VALUE(symbolVal(name)); /* create name */
3777 ex = newNode (FUNCTION,ex,body);
3778 ex->values.args = name->args ;
3781 werror(E_FUNC_NO_CODE,name->name);
3785 /* create the node & generate intermediate code */
3786 codeOutFile = code->oFile;
3787 piCode = iCodeFromAst(ex);
3790 werror(E_FUNC_NO_CODE,name->name);
3794 eBBlockFromiCode(piCode);
3796 /* if there are any statics then do them */
3798 codeOutFile = statsg->oFile;
3799 eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos))));
3805 /* dealloc the block variables */
3806 processBlockVars(body, &stack,DEALLOCATE);
3807 /* deallocate paramaters */
3808 deallocParms(name->args);
3810 if (IS_RENT(fetype))
3813 /* we are done freeup memory & cleanup */
3818 addSet(&operKeyReset,name);
3819 applyToSet(operKeyReset,resetParmKey);
3821 if (options.debug && !options.nodebug)
3822 cdbStructBlock(1,cdbFile);
3824 cleanUpLevel(LabelTab,0);
3825 cleanUpBlock(StructTab,1);
3826 cleanUpBlock(TypedefTab,1);
3828 xstack->syms = NULL;
3829 istack->syms = NULL;