/* forward definition of some functions */
operand *geniCodeDivision (operand *, operand *);
operand *geniCodeAssign (operand *, operand *, int);
-operand *geniCodeArray (operand *, operand *,int);
-operand *geniCodeArray2Ptr (operand *);
+static operand *geniCodeArray (operand *, operand *,int);
+static operand *geniCodeArray2Ptr (operand *);
operand *geniCodeRValue (operand *, bool);
operand *geniCodeDerefPtr (operand *,int);
int isLvaluereq(int lvl);
case LEFT_OP:
/* The number of left shifts is always unsigned. Signed doesn't make
sense here. Shifting by a negative number is impossible. */
- retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
- (TYPE_UDWORD) operandLitValue (right));
+ retval = operandFromValue (valCastLiteral (type,
+ ((TYPE_UDWORD) operandLitValue (left) <<
+ (TYPE_UDWORD) operandLitValue (right))));
break;
case RIGHT_OP:
/* The number of right shifts is always unsigned. Signed doesn't make
and before liveRange calculation */
sym->reqv = newiTempOperand (sym->type, 0);
sym->reqv->key = sym->key;
+ OP_SYMBOL (sym->reqv)->prereqv = sym;
OP_SYMBOL (sym->reqv)->key = sym->key;
OP_SYMBOL (sym->reqv)->isreqv = 1;
OP_SYMBOL (sym->reqv)->islocal = 1;
/*-----------------------------------------------------------------*/
/* perform "usual unary conversions" */
/*-----------------------------------------------------------------*/
+#if 0
static operand *
usualUnaryConversions (operand * op)
{
}
return op;
}
+#endif
/*-----------------------------------------------------------------*/
/* perform "usual binary conversions" */
This if for 'mul a,b', which takes two chars and returns an int */
if ( isMul
/* && promoteCharToInt superfluous, already handled by computeType() */
- && IS_CHAR (getSpec (ltype))
- && IS_CHAR (getSpec (rtype))
- && !(IS_UNSIGNED (getSpec (rtype)) ^ IS_UNSIGNED (getSpec (ltype)))
&& IS_INT (getSpec (ctype)))
- return ctype;
+ {
+ sym_link *retype = getSpec (rtype);
+ sym_link *letype = getSpec (ltype);
+ if ( IS_CHAR (letype)
+ && IS_CHAR (retype)
+ && IS_UNSIGNED (letype)
+ && IS_UNSIGNED (retype))
+ {
+ return ctype;
+ }
+ }
*op1 = geniCodeCast (ctype, *op1, TRUE);
*op2 = geniCodeCast (ctype, *op2, TRUE);
return op;
}
+ if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
+ {
+ geniCodeArray2Ptr (op);
+ op->isaddr = 0;
+ }
+
/* if the operand is already the desired type then do nothing */
if (compareType (type, optype) == 1)
return op;
}
/* if they are the same size create an assignment */
+
+ /* This seems very dangerous to me, since there are several */
+ /* optimizations (for example, gcse) that don't notice the */
+ /* cast hidden in this assignement and may simplify an */
+ /* iCode to use the original (uncasted) operand. */
+ /* Unfortunately, other things break when this cast is */
+ /* made explicit. Need to fix this someday. */
+ /* -- EEP, 2004/01/21 */
if (getSize (type) == getSize (optype) &&
!IS_BITFIELD (type) &&
!IS_FLOAT (type) &&
sym_link *ltype = operandType (left);
sym_link *letype = getSpec (ltype);
- resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
+ resType = usualBinaryConversions (&left, &right,
+ (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
+ FALSE);
/* if the right is a literal & power of 2
and left is unsigned then make it a
return operandFromValue (valMod (left->operand.valOperand,
right->operand.valOperand));
- resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
+ resType = usualBinaryConversions (&left, &right,
+ (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
+ FALSE);
/* now they are the same size */
ic = newiCode ('%', left, right);
if (getSize (ltype->next) != 1)
{
size = operandFromLit (getSize (ltype->next));
+ SPEC_USIGN (getSpec (operandType (size))) = 1;
indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
/* Even if right is a 'unsigned char',
/*-----------------------------------------------------------------*/
/* geniCodeArray2Ptr - array to pointer */
/*-----------------------------------------------------------------*/
-operand *
+static operand *
geniCodeArray2Ptr (operand * op)
{
sym_link *optype = operandType (op);
/*-----------------------------------------------------------------*/
/* geniCodeArray - array access */
/*-----------------------------------------------------------------*/
-operand *
-geniCodeArray (operand * left, operand * right,int lvl)
+static operand *
+geniCodeArray (operand * left, operand * right, int lvl)
{
iCode *ic;
+ operand *size;
sym_link *ltype = operandType (left);
bool indexUnsigned;
return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
}
+ size = operandFromLit (getSize (ltype->next));
+ SPEC_USIGN (getSpec (operandType (size))) = 1;
indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
- right = geniCodeMultiply (right,
- operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
+ right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
/* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
It doesn't make sense when accessing arrays, so let's fix it here: */
if (indexUnsigned)
SPEC_USIGN (getSpec (operandType (right))) = 1;
/* we can check for limits here */
+ /* already done in SDCCast.c
if (isOperandLiteral (right) &&
IS_ARRAY (ltype) &&
DCL_ELEM (ltype) &&
(operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
{
- werror (E_ARRAY_BOUND);
- right = operandFromLit (0);
+ werror (W_IDX_OUT_OF_BOUNDS,
+ (int) operandLitValue (right) / getSize (ltype->next),
+ DCL_ELEM (ltype));
}
+ */
ic = newiCode ('+', left, right);
{
iCode *ic;
- left = usualUnaryConversions (left);
ic = newiCode (LEFT_OP, left, right);
IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
ADDTOCHAIN (ic);
/*-----------------------------------------------------------------*/
value *
geniCodeParms (ast * parms, value *argVals, int *stack,
- sym_link * fetype, symbol * func,int lvl)
+ sym_link * ftype, int lvl)
{
iCode *ic;
operand *pval;
if (argVals==NULL) {
// first argument
- argVals=FUNC_ARGS(func->type);
+ argVals = FUNC_ARGS (ftype);
}
/* if this is a param node then do the left & right */
if (parms->type == EX_OP && parms->opval.op == PARAM)
{
- argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
- argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
+ argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
+ argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
return argVals;
}
}
/* if register parm then make it a send */
- if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
- IFFUNC_ISBUILTIN(func->type))
+ if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
+ IFFUNC_ISBUILTIN(ftype))
{
ic = newiCode (SEND, pval, NULL);
ic->argreg = SPEC_ARGREG(parms->etype);
- ic->builtinSEND = FUNC_ISBUILTIN(func->type);
+ ic->builtinSEND = FUNC_ISBUILTIN(ftype);
ADDTOCHAIN (ic);
}
else
{
/* now decide whether to push or assign */
- if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
+ if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
{
/* assign */
iCode *ic;
operand *result;
sym_link *type, *etype;
+ sym_link *ftype;
int stack = 0;
if (!IS_FUNC(OP_SYMBOL(left)->type) &&
of overlaying function parameters */
geniCodeSEParms (parms,lvl);
+ ftype = operandType (left);
+ if (IS_CODEPTR (ftype))
+ ftype = ftype->next;
+
/* first the parameters */
- geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
+ geniCodeParms (parms, NULL, &stack, ftype, lvl);
/* now call : if symbol then pcall */
if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
ic = newiCode (CALL, left, NULL);
}
- type = copyLinkChain (operandType (left)->next);
+ type = copyLinkChain (ftype->next);
etype = getSpec (type);
SPEC_EXTR (etype) = 0;
IC_RESULT (ic) = result = newiTempOperand (type, 1);
/*-----------------------------------------------------------------*/
/* geniCodeArrayInit - intermediate code for array initializer */
/*-----------------------------------------------------------------*/
-static void
+static void
geniCodeArrayInit (ast * tree, operand *array)
{
iCode *ic;
return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
case '-':
- if (right)
+ if (right)
return geniCodeSubtract (geniCodeRValue (left, FALSE),
geniCodeRValue (right, FALSE));
else