int noLineno = 0;
int noAlloc = 0;
symbol *currFunc=NULL;
-static ast *createIval (ast *, sym_link *, initList *, ast *);
-static ast *createIvalCharPtr (ast *, sym_link *, ast *);
+static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
+static ast *createIvalCharPtr (ast *, sym_link *, ast *, 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;
}
/* save it */
- addSymChain (sym);
+ addSymChain (&sym);
sym->cdef = 1;
allocVariables (sym);
return sym;
}
/* save it */
- addSymChain (sym);
+ addSymChain (&sym);
sym->cdef = 1;
allocVariables (sym);
return sym;
/* 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 */
/* createIvalStruct - generates initial value for structures */
/*-----------------------------------------------------------------*/
static ast *
-createIvalStruct (ast * sym, sym_link * type, initList * ilist)
+createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
{
ast *rast = NULL;
ast *lAst;
sflds->implicit = 1;
lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
- rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
+ rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
+ iloop, rast, rootValue)),
+ RESULT_TYPE_NONE);
+
}
if (iloop) {
/* createIvalArray - generates code for array initialization */
/*-----------------------------------------------------------------*/
static ast *
-createIvalArray (ast * sym, sym_link * type, initList * ilist)
+createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
{
ast *rast = NULL;
initList *iloop;
if (IS_CHAR (type->next))
if ((rast = createIvalCharPtr (sym,
type,
- decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
+ decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
+ rootValue)))
return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
- /* not the special case */
- if (ilist->type != INIT_DEEP)
- {
- werror (E_INIT_STRUCT, "");
- return NULL;
- }
+ /* not the special case */
+ if (ilist->type != INIT_DEEP)
+ {
+ werror (E_INIT_STRUCT, "");
+ return NULL;
+ }
- iloop = ilist->init.deep;
- lcnt = DCL_ELEM (type);
+ iloop = ilist->init.deep;
+ lcnt = DCL_ELEM (type);
- if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
- {
- ast *aSym;
+ if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
+ {
+ ast *aSym;
- aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
-
- rast = newNode(ARRAYINIT, aSym, NULL);
- rast->values.constlist = literalL;
-
- // Make sure size is set to length of initializer list.
- while (iloop)
- {
- size++;
- iloop = iloop->next;
- }
-
- if (lcnt && size > lcnt)
- {
- // Array size was specified, and we have more initializers than needed.
- char *name=sym->opval.val->sym->name;
- int lineno=sym->opval.val->sym->lineDef;
- char *filename=sym->opval.val->sym->fileDef;
-
- werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
- }
- }
- else
- {
- for (;;)
- {
- ast *aSym;
-
- aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
- aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
- rast = createIval (aSym, type->next, iloop, rast);
- iloop = (iloop ? iloop->next : NULL);
- if (!iloop)
- {
- break;
- }
-
- /* no of elements given and we */
- /* have generated for all of them */
- if (!--lcnt)
- {
- // is this a better way? at least it won't crash
- char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
- int lineno = iloop->lineno;
- char *filename = iloop->filename;
- werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
-
- break;
- }
- }
- }
+ aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
+
+ rast = newNode(ARRAYINIT, aSym, NULL);
+ rast->values.constlist = literalL;
+
+ // Make sure size is set to length of initializer list.
+ while (iloop)
+ {
+ size++;
+ iloop = iloop->next;
+ }
+
+ if (lcnt && size > lcnt)
+ {
+ // Array size was specified, and we have more initializers than needed.
+ char *name=sym->opval.val->sym->name;
+ int lineno=sym->opval.val->sym->lineDef;
+ char *filename=sym->opval.val->sym->fileDef;
+
+ werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ ast *aSym;
+
+ aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
+ aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
+ rast = createIval (aSym, type->next, iloop, rast, rootValue);
+ iloop = (iloop ? iloop->next : NULL);
+ if (!iloop)
+ {
+ break;
+ }
+
+ /* no of elements given and we */
+ /* have generated for all of them */
+ if (!--lcnt)
+ {
+ // is this a better way? at least it won't crash
+ char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
+ int lineno = iloop->lineno;
+ char *filename = iloop->filename;
+ werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
+
+ break;
+ }
+ }
+ }
- /* if we have not been given a size */
- if (!DCL_ELEM (type))
+ /* if we have not been given a size */
+ if (!DCL_ELEM (type))
{
- /* but this still updates the typedef instead of the instance ! see bug 770487 */
+ /* check, if it's a flexible array */
+ if (IS_STRUCT (AST_VALUE (rootValue)->type))
+ AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
+ else
DCL_ELEM (type) = size;
}
- return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
+ return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
}
/* createIvalCharPtr - generates initial values for char pointers */
/*-----------------------------------------------------------------*/
static ast *
-createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
+createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
{
ast *rast = NULL;
+ unsigned size = 0;
/* if this is a pointer & right is a literal array then */
/* just assignment will do */
/* to the array element */
char *s = SPEC_CVAL (iexpr->etype).v_char;
int i = 0;
- int size = getSize (iexpr->ftype);
int symsize = getSize (type);
-
- if (size>symsize)
+
+ size = getSize (iexpr->ftype);
+ if (symsize && size>symsize)
{
if (size>(symsize+1))
- werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
- "string", sym->opval.val->sym->name);
+ {
+ char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
+
+ werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
+ "string", name);
+ }
size = symsize;
}
// now WE don't need iexpr's symbol anymore
freeStringSymbol(AST_SYMBOL(iexpr));
+ /* if we have not been given a size */
+ if (!DCL_ELEM (type))
+ {
+ /* check, if it's a flexible array */
+ if (IS_STRUCT (AST_VALUE (rootVal)->type))
+ AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
+ else
+ DCL_ELEM (type) = size;
+ }
+
return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
}
/* createIvalPtr - generates initial value for pointers */
/*-----------------------------------------------------------------*/
static ast *
-createIvalPtr (ast * sym, sym_link * type, initList * ilist)
+createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
{
ast *rast;
ast *iexpr;
/* if character pointer */
if (IS_CHAR (type->next))
- if ((rast = createIvalCharPtr (sym, type, iexpr)))
+ if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
return rast;
return newNode ('=', sym, iexpr);
/* createIval - generates code for initial value */
/*-----------------------------------------------------------------*/
static ast *
-createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
+createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
{
ast *rast = NULL;
/* if structure then */
if (IS_STRUCT (type))
- rast = createIvalStruct (sym, type, ilist);
+ rast = createIvalStruct (sym, type, ilist, rootValue);
else
/* if this is a pointer */
if (IS_PTR (type))
- rast = createIvalPtr (sym, type, ilist);
+ rast = createIvalPtr (sym, type, ilist, rootValue);
else
/* if this is an array */
if (IS_ARRAY (type))
- rast = createIvalArray (sym, type, ilist);
+ rast = createIvalArray (sym, type, ilist, rootValue);
else
/* if type is SPECIFIER */
if (IS_SPEC (type))
/* initAggregates - initialises aggregate variables with initv */
/*-----------------------------------------------------------------*/
ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
- return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
+ ast *newAst = newAst_VALUE (symbolVal (sym));
+ return createIval (newAst, sym->type, ival, wid, newAst);
}
/*-----------------------------------------------------------------*/
if (noAlloc == 0)
{
/* allocate it */
- addSymChain (sym);
+ addSymChain (&sym);
allocVariables (sym);
}
sym->ival = NULL;
}
}
+ else
+ return FALSE;
/* check loop expression is of the form <sym>++ */
if (!IS_AST_OP (loopExpr))
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))
/* 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;
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;
}
#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)
{
switch (tree->opval.op)
{
+ case AND_OP:
+ case OR_OP:
+ return resultType;
case '=':
case '?':
case ':':
/* 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_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);
/* 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)
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;
return tree;
}
LRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newCharLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
return tree;
/*------------------------------------------------------------------*/
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:
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)
{
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;
return tree;
}
LRVAL (tree) = RRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newCharLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
return tree;
/*------------------------------------------------------------------*/
tree->opval.val->type);
return tree;
}
+ /* if one is 'signed char ' and the other one is 'unsigned char' */
+ /* it's necessary to promote to int */
+ if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
+ (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
+ {
+ /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
+ if it's possible to use a 'signed char' */
+
+ /* is left a 'unsigned char'? */
+ 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)
+ {
+ /* 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)
+ {
+ SPEC_USIGN (LETYPE (tree)) = 0;
+ }
+ else
+ {
+ werror (W_CMP_SU_CHAR);
+ tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
+ tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
+ }
+ }
+
LRVAL (tree) = RRVAL (tree) = 1;
TTYPE (tree) = TETYPE (tree) = newCharLink ();
return tree;
case V_FLOAT:
typeofv = TYPEOF_FLOAT;
break;
+ case V_FIXED16X16:
+ typeofv = TYPEOF_FIXED16X16;
+ break;
case V_CHAR:
typeofv = TYPEOF_CHAR;
break;
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;
}
/* 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;
sym_link *functype;
parmNumber = 1;
- if (IS_CODEPTR(LTYPE(tree)))
+ if (IS_FUNCPTR (LTYPE (tree)))
functype = LTYPE (tree)->next;
else
functype = LTYPE (tree);
}
/*-----------------------------------------------------------------*/
-/* 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_TYPE_NONE);
+ 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);
}
/*-----------------------------------------------------------------*/
}
/*-----------------------------------------------------------------*/
-/* optimizeCompare - otimizes compares for bit variables */
+/* optimizeCompare - optimizes compares for bit variables */
/*-----------------------------------------------------------------*/
static ast *
optimizeCompare (ast * root)
}
else
{
- addSymChain (name);
+ addSymChain (&name);
allocVariables (name);
}
name->lastLine = mylineno;
/* set the stack pointer */
stackPtr = -port->stack.direction * port->stack.call_overhead;
- xstackPtr = -port->stack.direction * port->stack.call_overhead;
+ xstackPtr = 0;
if (IFFUNC_ISISR (name->type))
stackPtr -= port->stack.direction * port->stack.isr_overhead;
return;
/*------------------------------------------------------------------*/
/*----------------------------*/
- /* compliment */
+ /* complement */
/*----------------------------*/
case '~':
fprintf(outfile,"COMPL (%p) type (",tree);
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);