X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=108f6d73e7d4fc89eea38853d720f6c9dfad2cfd;hb=074adb199c4ec2a893012872d5020427a262f59c;hp=d0898d7e57991ae917bec7466355cc07a7ea8f4c;hpb=6d5732239ca066c1757ae16f69942fd4b320e612;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index d0898d7e..108f6d73 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -55,7 +55,10 @@ static ast *createIvalCharPtr (ast *, sym_link *, ast *); static ast *optimizeCompare (ast *); ast *optimizeRRCRLC (ast *); ast *optimizeSWAP (ast *); -ast *optimizeGetHbit (ast *); +ast *optimizeGetHbit (ast *, RESULT_TYPE); +ast *optimizeGetAbit (ast *, RESULT_TYPE); +ast *optimizeGetByte (ast *, RESULT_TYPE); +ast *optimizeGetWord (ast *, RESULT_TYPE); ast *backPatchLabels (ast *, symbol *, symbol *); void PA(ast *t); int inInitMode = 0; @@ -218,6 +221,7 @@ copyAst (ast * src) dest->lineno = src->lineno; dest->level = src->level; dest->funcName = src->funcName; + dest->reversed = src->reversed; if (src->ftype) dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype)); @@ -572,7 +576,7 @@ funcOfType (char *name, sym_link * type, sym_link * argType, } /* save it */ - addSymChain (sym); + addSymChain (&sym); sym->cdef = 1; allocVariables (sym); return sym; @@ -612,7 +616,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes) } /* save it */ - addSymChain (sym); + addSymChain (&sym); sym->cdef = 1; allocVariables (sym); return sym; @@ -630,11 +634,25 @@ reverseParms (ast * ptree) return; /* top down if we find a nonParm tree then quit */ - if (ptree->type == EX_OP && ptree->opval.op == PARAM) + if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed) { + /* The various functions expect the parameter tree to be right heavy. */ + /* Rotate the tree to be left heavy so that after reversal it is */ + /* right heavy again. */ + while ((ttree = ptree->right) && ttree->type == EX_OP && + ttree->opval.op == PARAM) + { + ptree->right = ttree->right; + ttree->right = ttree->left; + ttree->left = ptree->left; + ptree->left = ttree; + } + + /* Now reverse */ ttree = ptree->left; ptree->left = ptree->right; ptree->right = ttree; + ptree->reversed = 1; reverseParms (ptree->left); reverseParms (ptree->right); } @@ -678,11 +696,15 @@ processParms (ast *func, /* if the function is being called via a pointer & */ /* it has not been defined a reentrant then we cannot */ /* have parameters */ - if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto) + /* PIC16 port can... */ + if (!TARGET_IS_PIC16) { - werror (W_NONRENT_ARGS); - fatalError++; - return 1; + if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto) + { + werror (W_NONRENT_ARGS); + fatalError++; + return 1; + } } /* if defined parameters ended but actual parameters */ @@ -834,8 +856,8 @@ createIvalType (ast * sym, sym_link * type, initList * ilist) if (ilist->type == INIT_DEEP) ilist = ilist->init.deep; - iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK); - return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK); + iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE); + return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE); } /*-----------------------------------------------------------------*/ @@ -865,8 +887,8 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist) break; sflds->implicit = 1; lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds))); - lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK); - rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK); + lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE); + rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE); } if (iloop) { @@ -896,9 +918,9 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) if (IS_CHAR (type->next)) if ((rast = createIvalCharPtr (sym, type, - decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK)))) + decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE)))) - return decorateType (resolveSymbols (rast), RESULT_CHECK); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); /* not the special case */ if (ilist->type != INIT_DEEP) @@ -914,7 +936,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) { ast *aSym; - aSym = decorateType (resolveSymbols(sym), RESULT_CHECK); + aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE); rast = newNode(ARRAYINIT, aSym, NULL); rast->values.constlist = literalL; @@ -943,7 +965,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) ast *aSym; aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); - aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK); + aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE); rast = createIval (aSym, type->next, iloop, rast); iloop = (iloop ? iloop->next : NULL); if (!iloop) @@ -973,7 +995,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) DCL_ELEM (type) = size; } - return decorateType (resolveSymbols (rast), RESULT_CHECK); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } @@ -1027,7 +1049,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) // now WE don't need iexpr's symbol anymore freeStringSymbol(AST_SYMBOL(iexpr)); - return decorateType (resolveSymbols (rast), RESULT_CHECK); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } return NULL; @@ -1046,7 +1068,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist) if (ilist->type == INIT_DEEP) ilist = ilist->init.deep; - iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK); + iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE); /* if character pointer */ if (IS_CHAR (type->next)) @@ -1084,9 +1106,9 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) rast = createIvalType (sym, type, ilist); if (wid) - return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK); + return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE); else - return decorateType (resolveSymbols (rast), RESULT_CHECK); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } /*-----------------------------------------------------------------*/ @@ -1115,6 +1137,21 @@ gatherAutoInit (symbol * autoChain) if (sym->ival) resolveIvalSym (sym->ival, sym->type); +#if 1 + /* if we are PIC16 port, + * and this is a static, + * and have initial value, + * and not S_CODE, don't emit in gs segment, + * but allow glue.c:pic16emitRegularMap to put symbol + * in idata section */ + if(TARGET_IS_PIC16 && + IS_STATIC (sym->etype) && sym->ival + && SPEC_SCLS(sym->etype) != S_CODE) { + SPEC_SCLS (sym->etype) = S_DATA; + continue; + } +#endif + /* if this is a static variable & has an */ /* initial value the code needs to be lifted */ /* here to the main portion since they can be */ @@ -1249,7 +1286,7 @@ stringToSymbol (value * val) if (noAlloc == 0) { /* allocate it */ - addSymChain (sym); + addSymChain (&sym); allocVariables (sym); } sym->ival = NULL; @@ -1302,7 +1339,7 @@ bool constExprTree (ast *cexpr) { return TRUE; } - cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK); + cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE); switch (cexpr->type) { @@ -1366,7 +1403,7 @@ bool constExprTree (ast *cexpr) { value * constExprValue (ast * cexpr, int check) { - cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK); + cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE); /* if this is not a constant then */ if (!IS_LITERAL (cexpr->ftype)) @@ -1499,6 +1536,8 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, } } + else + return FALSE; /* check loop expression is of the form ++ */ if (!IS_AST_OP (loopExpr)) @@ -1720,6 +1759,9 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) case '%': case LEFT_OP: case RIGHT_OP: + case GETABIT: + case GETBYTE: + case GETWORD: if (IS_AST_SYM_VALUE (pbody->left) && isSymbolEqual (AST_SYMBOL (pbody->left), sym)) @@ -1961,7 +2003,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) rloop)))); rloop->lineno=init->lineno; - return decorateType (rloop, RESULT_CHECK); + return decorateType (rloop, RESULT_TYPE_NONE); } @@ -2045,7 +2087,7 @@ getResultTypeFromType (sym_link *type) /* addCast - adds casts to a type specified by RESULT_TYPE */ /*-----------------------------------------------------------------*/ static ast * -addCast (ast *tree, RESULT_TYPE resultType, bool upcast) +addCast (ast *tree, RESULT_TYPE resultType, bool promote) { sym_link *newLink; bool upCasted = FALSE; @@ -2053,16 +2095,30 @@ addCast (ast *tree, RESULT_TYPE resultType, bool upcast) switch (resultType) { case RESULT_TYPE_NONE: - /* char: promote to int */ - if (!upcast || + /* if thing smaller than int must be promoted to int */ + if (!promote || getSize (tree->etype) >= INTSIZE) + /* promotion not necessary or already an int */ + return tree; + /* char and bits: promote to int */ + newLink = newIntLink(); + upCasted = TRUE; + break; + case RESULT_TYPE_BIT: + if (!promote || + /* already an int */ + bitsForType (tree->etype) >= 16 || + /* bit to bit operation: don't promote, the code generators + hopefully know everything about promotion rules */ + bitsForType (tree->etype) == 1) return tree; newLink = newIntLink(); upCasted = TRUE; break; case RESULT_TYPE_CHAR: if (IS_CHAR (tree->etype) || - IS_FLOAT(tree->etype)) + IS_FLOAT(tree->etype) || + IS_FIXED(tree->etype)) return tree; newLink = newCharLink(); break; @@ -2075,14 +2131,14 @@ addCast (ast *tree, RESULT_TYPE resultType, bool upcast) } #endif /* char: promote to int */ - if (!upcast || + if (!promote || getSize (tree->etype) >= INTSIZE) return tree; newLink = newIntLink(); upCasted = TRUE; break; case RESULT_TYPE_OTHER: - if (!upcast) + if (!promote) return tree; /* return type is long, float: promote char to int */ if (getSize (tree->etype) >= INTSIZE) @@ -2111,6 +2167,9 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType) { switch (tree->opval.op) { + case AND_OP: + case OR_OP: + return resultType; case '=': case '?': case ':': @@ -2560,10 +2619,37 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* see if this is a GETHBIT operation if yes then return that */ { - ast *otree = optimizeGetHbit (tree); + ast *otree = optimizeGetHbit (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETABIT operation if yes + then return that */ + { + ast *otree = optimizeGetAbit (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETBYTE operation if yes + then return that */ + { + ast *otree = optimizeGetByte (tree, resultType); if (otree != tree) - return decorateType (otree, RESULT_CHECK); + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETWORD operation if yes + then return that */ + { + ast *otree = optimizeGetWord (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); } /* if left is a literal exchange left & right */ @@ -2689,15 +2775,15 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* bitwise or */ /*----------------------------*/ case '|': - /* if the rewrite succeeds then don't go any furthur */ + /* if the rewrite succeeds then don't go any further */ { ast *wtree = optimizeRRCRLC (tree); if (wtree != tree) - return decorateType (wtree, RESULT_CHECK); + return decorateType (wtree, RESULT_TYPE_NONE); wtree = optimizeSWAP (tree); if (wtree != tree) - return decorateType (wtree, RESULT_CHECK); + return decorateType (wtree, RESULT_TYPE_NONE); } /* if left is a literal exchange left & right */ @@ -2850,7 +2936,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) else { /* litTree->left is literal: no gcse possible. - We can't call decorateType(parent, RESULT_CHECK), because + We can't call decorateType(parent, RESULT_TYPE_NONE), because this would cause an infinit loop. */ parent->decorated = 1; decorateType (litTree, resultType); @@ -3336,7 +3422,23 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; return addCast (tree, resultType, TRUE); } - tree->left = addCast (tree->left, resultType, TRUE); + + if (resultType == RESULT_TYPE_BIT && + IS_UNSIGNED (tree->left->etype) && + getSize (tree->left->etype) < INTSIZE) + { + /* promotion rules are responsible for this strange result: + bit -> int -> ~int -> bit + uchar -> int -> ~int -> bit + */ + werror(W_COMPLEMENT); + + /* optimize bit-result, even if we optimize a buggy source */ + tree->type = EX_VALUE; + tree->opval.val = constVal ("1"); + } + else + tree->left = addCast (tree->left, resultType, TRUE); LRVAL (tree) = 1; COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); return tree; @@ -3365,7 +3467,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; } LRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); return tree; /*------------------------------------------------------------------*/ @@ -3380,7 +3482,16 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; case GETHBIT: - TTYPE (tree) = TETYPE (tree) = newCharLink (); + case GETABIT: + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); + return tree; + + case GETBYTE: + TTYPE (tree) = TETYPE (tree) = newCharLink(); + return tree; + + case GETWORD: + TTYPE (tree) = TETYPE (tree) = newIntLink(); return tree; case LEFT_OP: @@ -3414,6 +3525,24 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; } + /* see if this is a GETBYTE operation if yes + then return that */ + { + ast *otree = optimizeGetByte (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETWORD operation if yes + then return that */ + { + ast *otree = optimizeGetWord (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + LRVAL (tree) = RRVAL (tree) = 1; if (tree->opval.op == LEFT_OP) { @@ -3529,11 +3658,37 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_ADDRESS_OF_OP(tree->right) && IS_AST_SYM_VALUE (tree->right->left) && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) { + + symbol * sym = AST_SYMBOL (tree->right->left); + unsigned int gptype = 0; + unsigned int addr = SPEC_ADDR (sym->etype); + if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE) + { + switch (SPEC_SCLS (sym->etype)) + { + case S_CODE: + gptype = GPTYPE_CODE; + break; + case S_XDATA: + gptype = GPTYPE_FAR; + break; + case S_DATA: + case S_IDATA: + gptype = GPTYPE_NEAR; + break; + case S_PDATA: + gptype = GPTYPE_XSTACK; + break; + default: + gptype = 0; + } + addr |= gptype << (8*(GPTRSIZE - 1)); + } + tree->type = EX_VALUE; tree->opval.val = - valCastLiteral (LTYPE (tree), - SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype)); + valCastLiteral (LTYPE (tree), addr); TTYPE (tree) = tree->opval.val->type; TETYPE (tree) = getSpec (TTYPE (tree)); tree->left = NULL; @@ -3672,7 +3827,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; } LRVAL (tree) = RRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); return tree; /*------------------------------------------------------------------*/ @@ -3757,7 +3912,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->right); /* val 0 */ tree->right->lineno = tree->lineno; tree->right->left->lineno = tree->lineno; - decorateType (tree->right, RESULT_CHECK); + decorateType (tree->right, RESULT_TYPE_NONE); } } /* if they are both literal then */ @@ -3815,6 +3970,9 @@ decorateType (ast * tree, RESULT_TYPE resultType) case V_FLOAT: typeofv = TYPEOF_FLOAT; break; + case V_FIXED16X16: + typeofv = TYPEOF_FIXED16X16; + break; case V_CHAR: typeofv = TYPEOF_CHAR; break; @@ -3899,7 +4057,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) case ':': /* if they don't match we have a problem */ - if (compareType (LTYPE (tree), RTYPE (tree)) == 0) + if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) && + (compareType (RTYPE (tree), LTYPE (tree)) == 0)) { werror (E_TYPE_MISMATCH, "conditional operator", " "); goto errorTreeReturn; @@ -4044,7 +4203,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) goto errorTreeReturn; } - tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK); + tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE); tree->opval.op = '='; return tree; @@ -4115,8 +4274,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) } /* require a function or pointer to function */ - if (!IS_FUNC (LTYPE (tree)) - && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next))) + if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree))) { werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED); goto errorTreeReturn; @@ -4130,7 +4288,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) sym_link *functype; parmNumber = 1; - if (IS_CODEPTR(LTYPE(tree))) + if (IS_FUNCPTR (LTYPE (tree))) functype = LTYPE (tree)->next; else functype = LTYPE (tree); @@ -4182,7 +4340,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) decorateType (newNode (CAST, newAst_LINK (copyLinkChain (currFunc->type->next)), tree->right), - RESULT_CHECK); + RESULT_TYPE_NONE); } RRVAL (tree) = 1; @@ -4231,9 +4389,9 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case FOR: - decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK); - decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK); - decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK); + decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE); + decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE); + decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE); /* if the for loop is reversible then reverse it otherwise do what we normally @@ -4252,7 +4410,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) AST_FOR (tree, initExpr), AST_FOR (tree, condExpr), AST_FOR (tree, loopExpr), - tree->left), RESULT_CHECK); + tree->left), RESULT_TYPE_NONE); } case PARAM: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, @@ -4416,7 +4574,6 @@ createBlock (symbol * decl, ast * body) ex = newNode (BLOCK, NULL, body); ex->values.sym = decl; - ex->right = ex->right;///????? ex->level++; ex->lineno = 0; return ex; @@ -4477,7 +4634,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) return NULL; } - caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK); + caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE); /* if not a constant then error */ if (!IS_LITERAL (caseVal->ftype)) { @@ -4802,41 +4959,194 @@ createWhile (symbol * trueLabel, symbol * continueLabel, } /*-----------------------------------------------------------------*/ -/* optimizeGetHbit - get highest order bit of the expression */ +/* isShiftRightLitVal _BitAndLitVal - helper function */ /*-----------------------------------------------------------------*/ -ast * -optimizeGetHbit (ast * tree) +static ast * +isShiftRightLitVal_BitAndLitVal (ast * tree) { - int i, j; /* if this is not a bit and */ if (!IS_BITAND (tree)) - return tree; + return NULL; /* will look for tree of the form - ( expr >> ((sizeof expr) -1) ) & 1 */ + ( expr >> litval2) & litval1 */ if (!IS_AST_LIT_VALUE (tree->right)) + return NULL; + + if (!IS_RIGHT_OP (tree->left)) + return NULL; + + if (!IS_AST_LIT_VALUE (tree->left->right)) + return NULL; + + return tree->left->left; +} + +/*-----------------------------------------------------------------*/ +/* isBitAndPowOf2 - helper function */ +/*-----------------------------------------------------------------*/ +static int +isBitAndPow2 (ast * tree) +{ + /* if this is not a bit and */ + if (!IS_BITAND (tree)) + return -1; + + /* will look for tree of the form + ( expr & (1 << litval) */ + if (!IS_AST_LIT_VALUE (tree->right)) + return -1; + + return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right)); +} + +/*-----------------------------------------------------------------*/ +/* optimizeGetHbit - get highest order bit of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetHbit (ast * tree, RESULT_TYPE resultType) +{ + int i, j; + ast * expr; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + if ((AST_LIT_VALUE (tree->right) != 1) || + ((i = (int) AST_LIT_VALUE (tree->left->right)) != + (j = (getSize (TTYPE (expr)) * 8 - 1)))) + expr = NULL; + } + if (!expr && (resultType == RESULT_TYPE_BIT)) + { + expr = tree->left; + if (isBitAndPow2 (tree) != getSize (TTYPE (expr)) * 8 - 1) + expr = NULL; + } + if (!expr) return tree; - if (AST_LIT_VALUE (tree->right) != 1) + /* make sure the port supports GETHBIT */ + if (port->hasExtBitOp + && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr)))) return tree; - if (!IS_RIGHT_OP (tree->left)) + return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE); +} + +/*-----------------------------------------------------------------*/ +/* optimizeGetAbit - get a single bit of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetAbit (ast * tree, RESULT_TYPE resultType) +{ + ast * expr; + ast * count = NULL; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + if (AST_LIT_VALUE (tree->right) != 1) + expr = NULL; + count = tree->left->right; + } + if (!expr && (resultType == RESULT_TYPE_BIT)) + { + int p2 = isBitAndPow2 (tree); + if (p2 >= 0) + { + expr = tree->left; + count = newAst_VALUE (valueFromLit (p2)); + } + } + if (!expr) return tree; - if (!IS_AST_LIT_VALUE (tree->left->right)) + /* make sure the port supports GETABIT */ + if (port->hasExtBitOp + && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr)))) return tree; - if ((i = (int) AST_LIT_VALUE (tree->left->right)) != - (j = (getSize (TTYPE (tree->left->left)) * 8 - 1))) + return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE); + +} + +/*-----------------------------------------------------------------*/ +/* optimizeGetByte - get a byte of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetByte (ast * tree, RESULT_TYPE resultType) +{ + unsigned int i = 0; + ast * expr; + ast * count = NULL; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + i = (unsigned int) AST_LIT_VALUE (tree->left->right); + count = tree->left->right; + if (AST_LIT_VALUE (tree->right) != 0xFF) + expr = NULL; + } + if (!expr && resultType == RESULT_TYPE_CHAR) + { + /* if this is a right shift over a multiple of 8 */ + if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right)) + { + i = (unsigned int) AST_LIT_VALUE (tree->right); + count = tree->right; + expr = tree->left; + } + } + if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8)) return tree; - /* make sure the port supports GETHBIT */ + /* make sure the port supports GETBYTE */ if (port->hasExtBitOp - && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left)))) + && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr)))) return tree; - return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK); + return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE); +} +/*-----------------------------------------------------------------*/ +/* optimizeGetWord - get two bytes of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetWord (ast * tree, RESULT_TYPE resultType) +{ + unsigned int i = 0; + ast * expr; + ast * count = NULL; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + i = (unsigned int) AST_LIT_VALUE (tree->left->right); + count = tree->left->right; + if (AST_LIT_VALUE (tree->right) != 0xFFFF) + expr = NULL; + } + if (!expr && resultType == RESULT_TYPE_INT) + { + /* if this is a right shift over a multiple of 8 */ + if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right)) + { + i = (unsigned int) AST_LIT_VALUE (tree->right); + count = tree->right; + expr = tree->left; + } + } + if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8)) + return tree; + + /* make sure the port supports GETWORD */ + if (port->hasExtBitOp + && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr)))) + return tree; + + return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE); } /*-----------------------------------------------------------------*/ @@ -5062,7 +5372,7 @@ optimizeSWAP (ast * root) } /*-----------------------------------------------------------------*/ -/* optimizeCompare - otimizes compares for bit variables */ +/* optimizeCompare - optimizes compares for bit variables */ /*-----------------------------------------------------------------*/ static ast * optimizeCompare (ast * root) @@ -5102,7 +5412,7 @@ optimizeCompare (ast * root) break; } - return decorateType (optExpr, RESULT_CHECK); + return decorateType (optExpr, RESULT_TYPE_NONE); } vleft = (root->left->type == EX_VALUE ? @@ -5176,7 +5486,7 @@ optimizeCompare (ast * root) break; } } - return decorateType (resolveSymbols (optExpr), RESULT_CHECK); + return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE); } /* end-of-if of BITVAR */ noOptimize: @@ -5279,21 +5589,26 @@ createFunction (symbol * name, ast * body) } else { - addSymChain (name); + addSymChain (&name); allocVariables (name); } name->lastLine = mylineno; currFunc = name; /* set the stack pointer */ - /* PENDING: check this for the mcs51 */ - stackPtr = -port->stack.direction * port->stack.call_overhead; + stackPtr = -port->stack.direction * port->stack.call_overhead; + xstackPtr = 0; + if (IFFUNC_ISISR (name->type)) stackPtr -= port->stack.direction * port->stack.isr_overhead; - if (IFFUNC_ISREENT (name->type) || options.stackAuto) - stackPtr -= port->stack.direction * port->stack.reent_overhead; - xstackPtr = -port->stack.direction * port->stack.call_overhead; + if (IFFUNC_ISREENT (name->type) || options.stackAuto) + { + if (options.useXstack) + xstackPtr -= port->stack.direction * port->stack.reent_overhead; + else + stackPtr -= port->stack.direction * port->stack.reent_overhead; + } fetype = getSpec (name->type); /* get the specifier for the function */ /* if this is a reentrant function then */ @@ -5354,7 +5669,7 @@ createFunction (symbol * name, ast * body) { GcurMemmap = statsg; codeOutFile = statsg->oFile; - eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK))); + eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE))); staticAutos = NULL; } @@ -5711,7 +6026,7 @@ void ast_print (ast * tree, FILE *outfile, int indent) return; /*------------------------------------------------------------------*/ /*----------------------------*/ - /* compliment */ + /* complement */ /*----------------------------*/ case '~': fprintf(outfile,"COMPL (%p) type (",tree); @@ -5758,6 +6073,27 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,")\n"); ast_print(tree->left,outfile,indent+2); return ; + case GETABIT: + fprintf(outfile,"GETABIT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case GETBYTE: + fprintf(outfile,"GETBYTE (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case GETWORD: + fprintf(outfile,"GETWORD (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; case LEFT_OP: fprintf(outfile,"LEFT_SHIFT (%p) type (",tree); printTypeChain(tree->ftype,outfile);