/*-----------------------------------------------------------------*/
/* gatherAutoInit - creates assignment expressions for initial */
-/* values */
+/* values */
/*-----------------------------------------------------------------*/
static ast *
gatherAutoInit (symbol * autoChain)
cexpr->opval.op == CAST &&
IS_LITERAL (cexpr->right->ftype))
{
- return valCastLiteral (cexpr->ftype,
- floatFromVal (cexpr->right->opval.val));
+ return valCastLiteral (cexpr->ftype,
+ floatFromVal (cexpr->right->opval.val));
}
if (IS_AST_VALUE (cexpr))
{
- return cexpr->opval.val;
+ return cexpr->opval.val;
}
if (check)
return isLabelInAst (label, tree->right) &&
isLabelInAst (label, tree->left);
-
}
/*-----------------------------------------------------------------*/
if (IS_AST_SYM_VALUE (loopExpr->left) &&
isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
IS_AST_LIT_VALUE (loopExpr->right) &&
- (int) AST_LIT_VALUE (loopExpr->right) != 1)
+ AST_ULONG_VALUE (loopExpr->right) != 1)
return TRUE;
}
}
{
case AND_OP:
case OR_OP:
- return resultType;
+ case '!':
case '=':
case '?':
case ':':
case '|':
case '^':
case '~':
+ case LEFT_OP:
+ case LABEL:
+ return resultType;
case '*':
case '+':
case '-':
- case LABEL:
+ if ((IS_AST_VALUE (tree->left) && !IS_INTEGRAL (tree->left->opval.val->etype)) ||
+ (IS_AST_VALUE (tree->right) && !IS_INTEGRAL (tree->right->opval.val->etype)))
+ return RESULT_TYPE_NONE;
return resultType;
case '&':
if (!tree->right)
upon tree->opval.op, if resultType can be propagated */
resultTypeProp = resultTypePropagate (tree, resultType);
- if (tree->opval.op == '?')
+ if ((tree->opval.op == '?') && (resultTypeProp != RESULT_TYPE_BIT))
dtl = decorateType (tree->left, RESULT_TYPE_IFX);
else
dtl = decorateType (tree->left, resultTypeProp);
if (IS_LITERAL (RTYPE (tree)))
{
- int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
+ int arrayIndex = (int) ulFromVal (valFromType (RETYPE (tree)));
int arraySize = DCL_ELEM (LTYPE (tree));
if (arraySize && arrayIndex >= arraySize)
{
/* rearrange the tree */
if (IS_LITERAL (RTYPE (tree))
/* avoid infinite loop */
- && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
+ && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 1)
{
ast *parent;
ast *litTree = searchLitOp (tree, &parent, "/");
}
LRVAL (tree) = RRVAL (tree) = 1;
- tree->left = addCast (tree->left, resultType, FALSE);
- tree->right = addCast (tree->right, resultType, FALSE);
+ tree->left = addCast (tree->left, resultTypeProp, FALSE);
+ tree->right = addCast (tree->right, resultTypeProp, FALSE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
{
tree->type = EX_VALUE;
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
tree->opval.val = valPlus (valFromType (LETYPE (tree)),
valFromType (RETYPE (tree)));
tree->right = tree->left = NULL;
LTYPE (tree));
else
{
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
return tree;
}
- tree->left = addCast (tree->left, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
NULL,
if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
{
tree->type = EX_VALUE;
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
tree->opval.val = valMinus (valFromType (LETYPE (tree)),
valFromType (RETYPE (tree)));
tree->right = tree->left = NULL;
LTYPE (tree));
else
{
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
/* rearrange the tree */
if (IS_LITERAL (RTYPE (tree))
/* avoid infinite loop */
- && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
+ && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 0)
{
ast *litTree, *litParent;
litTree = searchLitOp (tree, &litParent, "+-");
tree->opval.val = valComplement (valFromType (LETYPE (tree)));
tree->left = NULL;
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
- return addCast (tree, resultType, TRUE);
+ return addCast (tree, resultTypeProp, TRUE);
}
if (resultType == RESULT_TYPE_BIT &&
tree->opval.val = constVal ("1");
}
else
- tree->left = addCast (tree->left, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
LRVAL (tree) = 1;
COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
return tree;
}
/* if left is another '!' */
- if (tree->left->opval.op == '!')
+ if (IS_AST_NOT_OPER (tree->left))
{
+ if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
+ {
+ /* replace double '!!X' by 'X' */
+ return tree->left->left;
+ }
/* remove double '!!X' by 'X ? 1 : 0' */
tree->opval.op = '?';
tree->left = tree->left->left;
/* make smaller type only if it's a LEFT_OP */
if (tree->opval.op == LEFT_OP)
- tree->left = addCast (tree->left, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
/* if they are both literal then */
/* rewrite the tree */
/* if only the right side is a literal & we are
shifting more than size of the left operand then zero */
if (IS_LITERAL (RTYPE (tree)) &&
- ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
+ ((TYPE_TARGET_ULONG) ulFromVal (valFromType (RETYPE (tree)))) >=
(getSize (TETYPE (tree)) * 8))
{
if (tree->opval.op==LEFT_OP ||
TTYPE (tree) = tree->opval.val->type;
tree->values.literalFromCast = 1;
} else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
- ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
+ ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
sym_link *rest = LTYPE(tree)->next;
werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
TTYPE(tree) = newLink(DECLARATOR);
if (tree->opval.op == '>' &&
SPEC_USIGN(LETYPE(tree)) &&
IS_LITERAL(RTYPE(tree)) &&
- ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
+ ((int) ulFromVal (valFromType (RETYPE (tree)))) == 0)
{
- if (resultType == RESULT_TYPE_IFX)
+ if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
{
/* the parent is an ifx: */
/* if (unsigned value) */
if (IS_LITERAL(RTYPE(tree)) &&
floatFromVal (valFromType (RETYPE (tree))) == 0 &&
tree->opval.op == EQ_OP &&
- resultType == RESULT_TYPE_IFX)
+ (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT))
{
tree->opval.op = '!';
tree->right = NULL;
if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
/* the value range of a 'unsigned char' is 0...255;
if the actual value is < 128 it can be changed to signed */
- (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
+ (int) ulFromVal (valFromType (RETYPE (tree))) < 128)
{
/* now we've got 2 'signed char'! */
SPEC_USIGN (RETYPE (tree)) = 0;
}
/* same test for the left operand: */
else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
- (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
+ (int) ulFromVal (valFromType (LETYPE (tree))) < 128)
{
SPEC_USIGN (LETYPE (tree)) = 0;
}
}
LRVAL (tree) = RRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newBoolLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
/* condition transformations */
{
case '?':
/* the type is value of the colon operator (on the right) */
assert (IS_COLON_OP (tree->right));
- /* if already known then replace the tree : optimizer will do it
- but faster to do it here */
+
+ /* If already known then replace the tree : optimizer will do it
+ but faster to do it here. If done before decorating tree->right
+ this can save generating unused const strings. */
if (IS_LITERAL (LTYPE (tree)))
{
- if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
+ if (((int) ulFromVal (valFromType (LETYPE (tree)))) != 0)
return decorateType (tree->right->left, resultTypeProp);
else
return decorateType (tree->right->right, resultTypeProp);
}
- else
+
+ tree->right = decorateType (tree->right, resultTypeProp);
+
+ if (IS_AST_LIT_VALUE (tree->right->left) && IS_AST_LIT_VALUE (tree->right->right) &&
+ ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)))
{
- tree->right = decorateType (tree->right, resultTypeProp);
- TTYPE (tree) = RTYPE (tree);
- TETYPE (tree) = getSpec (TTYPE (tree));
+ double valTrue = AST_FLOAT_VALUE (tree->right->left);
+ double valFalse = AST_FLOAT_VALUE (tree->right->right);
+
+ if ((valTrue != 0) && (valFalse == 0))
+ {
+ /* assign cond to result */
+ tree->left->decorated = 0;
+ return decorateType (tree->left, resultTypeProp);
+ }
+ else if ((valTrue == 0) && (valFalse != 0))
+ {
+ /* assign !cond to result */
+ tree->opval.op = '!';
+ tree->decorated = 0;
+ tree->right = NULL;
+ return decorateType (tree, resultTypeProp);
+ }
+ else
+ {
+ /* they have the same boolean value, make them equal */
+ tree->right->left = tree->right->right;
+ }
+ }
+
+ /* if they are equal then replace the tree */
+ if (isAstEqual (tree->right->left, tree->right->right))
+ {
+ return tree->right->left;
}
+
+ TTYPE (tree) = RTYPE (tree);
+ TETYPE (tree) = getSpec (TTYPE (tree));
return tree;
case ':':
{
/* also order the cases according to value */
value *pval = NULL;
- int cVal = (int) floatFromVal (caseVal->opval.val);
- while (val && (int) floatFromVal (val) < cVal)
+ int cVal = (int) ulFromVal (caseVal->opval.val);
+ while (val && (int) ulFromVal (val) < cVal)
{
pval = val;
val = val->next;
{
pval->next = caseVal->opval.val;
}
- else if ((int) floatFromVal (val) == cVal)
+ else if ((int) ulFromVal (val) == cVal)
{
werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
"case");
SNPRINTF(caseLbl, sizeof(caseLbl),
"_case_%d_%d",
swStat->values.switchVals.swNum,
- (int) floatFromVal (caseVal->opval.val));
+ (int) ulFromVal (caseVal->opval.val));
rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
rexpr->lineno = 0;
if (!IS_AST_LIT_VALUE (tree->right))
return -1;
- return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
+ return powof2 (AST_ULONG_VALUE (tree->right));
}
/*-----------------------------------------------------------------*/
ast *
optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
{
- int i, j;
+ unsigned 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)) !=
+ if ((AST_ULONG_VALUE (tree->right) != 1) ||
+ ((i = AST_ULONG_VALUE (tree->left->right)) !=
(j = (getSize (TTYPE (expr)) * 8 - 1))))
expr = NULL;
}
expr = isShiftRightLitVal_BitAndLitVal(tree);
if (expr)
{
- if (AST_LIT_VALUE (tree->right) != 1)
+ if (AST_ULONG_VALUE (tree->right) != 1)
expr = NULL;
count = tree->left->right;
}
expr = isShiftRightLitVal_BitAndLitVal(tree);
if (expr)
{
- i = (unsigned int) AST_LIT_VALUE (tree->left->right);
+ i = AST_ULONG_VALUE (tree->left->right);
count = tree->left->right;
- if (AST_LIT_VALUE (tree->right) != 0xFF)
+ if (AST_ULONG_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);
+ i = AST_ULONG_VALUE (tree->right);
count = tree->right;
expr = tree->left;
}
expr = isShiftRightLitVal_BitAndLitVal(tree);
if (expr)
{
- i = (unsigned int) AST_LIT_VALUE (tree->left->right);
+ i = AST_ULONG_VALUE (tree->left->right);
count = tree->left->right;
- if (AST_LIT_VALUE (tree->right) != 0xFFFF)
+ if (AST_ULONG_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);
+ i = AST_ULONG_VALUE (tree->right);
count = tree->right;
expr = tree->left;
}
root->right->left))
goto tryNext0;
- if (AST_LIT_VALUE (root->left->right) != 1)
+ if (AST_ULONG_VALUE (root->left->right) != 1)
goto tryNext0;
- if (AST_LIT_VALUE (root->right->right) !=
+ if (AST_ULONG_VALUE (root->right->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
goto tryNext0;
root->right->left))
goto tryNext1;
- if (AST_LIT_VALUE (root->right->right) != 1)
+ if (AST_ULONG_VALUE (root->right->right) != 1)
goto tryNext1;
- if (AST_LIT_VALUE (root->left->right) !=
+ if (AST_ULONG_VALUE (root->left->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
goto tryNext1;
root->right->left))
goto tryNext2;
- if (AST_LIT_VALUE (root->left->right) != 1)
+ if (AST_ULONG_VALUE (root->left->right) != 1)
goto tryNext2;
- if (AST_LIT_VALUE (root->right->right) !=
+ if (AST_ULONG_VALUE (root->right->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
goto tryNext2;
root->right->left))
return root;
- if (AST_LIT_VALUE (root->right->right) != 1)
+ if (AST_ULONG_VALUE (root->right->right) != 1)
return root;
- if (AST_LIT_VALUE (root->left->right) !=
+ if (AST_ULONG_VALUE (root->left->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
return root;
root->right->left))
return root;
- if (AST_LIT_VALUE (root->left->right) !=
+ if (AST_ULONG_VALUE (root->left->right) !=
(getSize (TTYPE (root->left->left)) * 4))
return root;
- if (AST_LIT_VALUE (root->right->right) !=
+ if (AST_ULONG_VALUE (root->right->right) !=
(getSize (TTYPE (root->left->left)) * 4))
return root;
root->right->opval.val : NULL);
/* if left is a BITVAR in BITSPACE */
- /* and right is a LITERAL then opt- */
- /* imize else do nothing */
+ /* and right is a LITERAL then */
+ /* optimize else do nothing */
if (vleft && vright &&
IS_BITVAR (vleft->etype) &&
IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
{
/* if right side > 1 then comparison may never succeed */
- if ((litValue = (int) floatFromVal (vright)) > 1)
+ if ((litValue = (int) ulFromVal (vright)) > 1)
{
werror (W_BAD_COMPARE);
goto noOptimize;
return inlineFindParmRecurse (parms, &index);
}
+/*-----------------------------------------------------------------*/
+/* inlineFindMaxBlockno - find maximum block number in an ast tree */
+/*-----------------------------------------------------------------*/
+static int
+inlineFindMaxBlockno (ast * tree, int maxBlockno)
+{
+ int tempBlockno;
+
+ if (!tree)
+ return maxBlockno;
+
+ tempBlockno = inlineFindMaxBlockno (tree->left, maxBlockno);
+ if (tempBlockno > maxBlockno)
+ maxBlockno = tempBlockno;
+
+ tempBlockno = inlineFindMaxBlockno (tree->right, maxBlockno);
+ if (tempBlockno > maxBlockno)
+ maxBlockno = tempBlockno;
+
+ if (tree->block > maxBlockno)
+ maxBlockno = tree->block;
+ return maxBlockno;
+}
+
+
+
/*-----------------------------------------------------------------*/
/* expandInlineFuncs - replace calls to inline functions with the */
int stack = 0;
sym_link *fetype;
iCode *piCode = NULL;
+ int savedBlockno;
if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
reentrant++;
inlineState.count = 0;
+ savedBlockno = currBlockno;
+ currBlockno = inlineFindMaxBlockno (body, 0);
expandInlineFuncs (body, NULL);
+ currBlockno = savedBlockno;
if (FUNC_ISINLINE (name->type))
name->funcTree = copyAst (body);
if (IS_LITERAL (tree->opval.val->etype)) {
fprintf(outfile,"CONSTANT (%p) value = ", tree);
if (SPEC_USIGN (tree->opval.val->etype))
- fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
+ fprintf(outfile,"%u", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val));
else
- fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
- fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
+ fprintf(outfile,"%d", (TYPE_TARGET_LONG) ulFromVal(tree->opval.val));
+ fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val),
floatFromVal(tree->opval.val));
} else if (tree->opval.val->sym) {
/* if the undefined flag is set then give error message */
for (val = tree->values.switchVals.swVals; val ; val = val->next) {
INDENT(indent+2,outfile);
fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
- (int) floatFromVal(val),
+ (int) ulFromVal(val),
tree->values.switchVals.swNum,
- (int) floatFromVal(val));
+ (int) ulFromVal(val));
}
ast_print(tree->right,outfile,indent);
}