/*-----------------------------------------------------------------*/
/* forward definition of some functions */
-operand *geniCodeDivision (operand *, operand *);
-operand *geniCodeAssign (operand *, operand *, int);
-operand *geniCodeArray (operand *, operand *,int);
-operand *geniCodeArray2Ptr (operand *);
+operand *geniCodeAssign (operand *, operand *, int, int);
+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
(TYPE_UDWORD) operandLitValue (right));
break;
case EQ_OP:
- /* this op doesn't care about signedness */
- {
- TYPE_UDWORD l, r;
-
- l = (TYPE_UDWORD) operandLitValue (left);
- if (IS_CHAR(OP_VALUE(left)->type))
- l &= 0xff;
- else if (!IS_LONG (OP_VALUE(left)->type))
- l &= 0xffff;
- r = (TYPE_UDWORD) operandLitValue (right);
- if (IS_CHAR(OP_VALUE(right)->type))
- r &= 0xff;
- else if (!IS_LONG (OP_VALUE(right)->type))
- r &= 0xffff;
- retval = operandFromLit (l == r);
- }
+ if (IS_FLOAT (let) ||
+ IS_FLOAT (ret))
+ {
+ retval = operandFromLit (operandLitValue (left) ==
+ operandLitValue (right));
+ }
+ else
+ {
+ /* this op doesn't care about signedness */
+ TYPE_UDWORD l, r;
+
+ l = (TYPE_UDWORD) operandLitValue (left);
+ r = (TYPE_UDWORD) operandLitValue (right);
+ /* In order to correctly compare 'signed int' and 'unsigned int' it's
+ neccessary to strip them to 16 bit.
+ Literals are reduced to their cheapest type, therefore left and
+ right might have different types. It's neccessary to find a
+ common type: int (used for char too) or long */
+ if (!IS_LONG (let) &&
+ !IS_LONG (ret))
+ {
+ r = (TYPE_UWORD) r;
+ l = (TYPE_UWORD) l;
+ }
+ retval = operandFromLit (l == r);
+ }
break;
case '<':
retval = operandFromLit (operandLitValue (left) <
break;
case '~':
- retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
+ retval = operandFromValue (valCastLiteral (type,
+ ~((TYPE_UDWORD)
+ operandLitValue (left))));
break;
case '!':
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;
}
}
+
/*-----------------------------------------------------------------*/
/* Get size in byte of ptr need to access an array */
/*-----------------------------------------------------------------*/
-int
+static int
getArraySizePtr (operand * op)
{
sym_link *ltype = operandType(op);
/*-----------------------------------------------------------------*/
/* perform "usual unary conversions" */
/*-----------------------------------------------------------------*/
+#if 0
static operand *
usualUnaryConversions (operand * op)
{
}
return op;
}
+#endif
/*-----------------------------------------------------------------*/
/* perform "usual binary conversions" */
/*-----------------------------------------------------------------*/
+
static sym_link *
usualBinaryConversions (operand ** op1, operand ** op2,
- bool promoteCharToInt, bool isMul)
+ RESULT_TYPE resultType, int op)
{
sym_link *ctype;
sym_link *rtype = operandType (*op2);
sym_link *ltype = operandType (*op1);
- ctype = computeType (ltype, rtype, promoteCharToInt);
+ ctype = computeType (ltype, rtype, resultType, op);
- /* special for multiplication:
- 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;
+ switch (op)
+ {
+ case '*':
+ case '/':
+ case '%':
+ if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
+ {
+ /* one byte operations: keep signedness for code generator */
+ return ctype;
+ }
+ break;
+ default:
+ break;
+ }
*op1 = geniCodeCast (ctype, *op1, TRUE);
*op2 = geniCodeCast (ctype, *op2, TRUE);
-
+
return ctype;
}
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) &&
/* preserve the storage class & output class */
/* of the original variable */
restype = getSpec (operandType (IC_RESULT (ic)));
- if (!IS_LITERAL(opetype))
+ if (!IS_LITERAL(opetype) &&
+ !IS_BIT(opetype))
SPEC_SCLS (restype) = SPEC_SCLS (opetype);
SPEC_OCLS (restype) = SPEC_OCLS (opetype);
/*-----------------------------------------------------------------*/
/* geniCodeMultiply - gen intermediate code for multiplication */
/*-----------------------------------------------------------------*/
-operand *
-geniCodeMultiply (operand * left, operand * right, int resultIsInt)
+static operand *
+geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
{
iCode *ic;
int p2 = 0;
p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
}
- resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
+ resType = usualBinaryConversions (&left, &right, resultType, '*');
#if 1
rtype = operandType (right);
retype = getSpec (rtype);
/* code generated for 1 byte * 1 byte literal = 2 bytes result is more
efficient in most cases than 2 bytes result = 2 bytes << literal
if port has 1 byte muldiv */
- if (p2 && !IS_FLOAT (letype) &&
- !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
- (port->support.muldiv == 1)))
+ if (p2 && !IS_FLOAT (letype)
+ && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
+ && (port->support.muldiv == 1))
+ && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
+ && strcmp (port->target, "pic16") != 0)
{
- if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
+ if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
{
/* LEFT_OP need same size for left and result, */
left = geniCodeCast (resType, left, TRUE);
/*-----------------------------------------------------------------*/
/* geniCodeDivision - gen intermediate code for division */
/*-----------------------------------------------------------------*/
-operand *
-geniCodeDivision (operand * left, operand * right)
+static operand *
+geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
{
iCode *ic;
int p2 = 0;
sym_link *ltype = operandType (left);
sym_link *letype = getSpec (ltype);
- resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
+ resType = usualBinaryConversions (&left, &right, resultType, '/');
/* if the right is a literal & power of 2
and left is unsigned then make it a
/*-----------------------------------------------------------------*/
/* geniCodeModulus - gen intermediate code for modulus */
/*-----------------------------------------------------------------*/
-operand *
-geniCodeModulus (operand * left, operand * right)
+static operand *
+geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
{
iCode *ic;
sym_link *resType;
return operandFromValue (valMod (left->operand.valOperand,
right->operand.valOperand));
- resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
+ resType = usualBinaryConversions (&left, &right, resultType, '%');
/* now they are the same size */
ic = newiCode ('%', left, right);
// should we really do this? is this ANSI?
return geniCodeDivision (result,
- operandFromLit (getSize (ltype->next)));
+ operandFromLit (getSize (ltype->next)),
+ FALSE);
}
/*-----------------------------------------------------------------*/
/* geniCodeSubtract - generates code for subtraction */
/*-----------------------------------------------------------------*/
-operand *
-geniCodeSubtract (operand * left, operand * right)
+static operand *
+geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
{
iCode *ic;
int isarray = 0;
{
isarray = left->isaddr;
right = geniCodeMultiply (right,
- operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
+ operandFromLit (getSize (ltype->next)),
+ (getArraySizePtr(left) >= INTSIZE) ?
+ RESULT_TYPE_INT :
+ RESULT_TYPE_CHAR);
resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
}
else
{ /* make them the same size */
- resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
+ resType = usualBinaryConversions (&left, &right, resultType, '-');
}
ic = newiCode ('-', left, right);
/*-----------------------------------------------------------------*/
/* geniCodeAdd - generates iCode for addition */
/*-----------------------------------------------------------------*/
-operand *
-geniCodeAdd (operand * left, operand * right, int lvl)
+static operand *
+geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
{
iCode *ic;
sym_link *resType;
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));
+ right = geniCodeMultiply (right,
+ size,
+ (getArraySizePtr(left) >= INTSIZE) ?
+ RESULT_TYPE_INT :
+ RESULT_TYPE_CHAR);
/* 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: */
}
else
{ // make them the same size
- resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
+ resType = usualBinaryConversions (&left, &right, resultType, '+');
}
/* if they are both literals then we know */
return ptype;
}
+/*------------------------------------------------------------------*/
+/* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
+/*------------------------------------------------------------------*/
+int
+aggrToPtrDclType (sym_link * type, bool force)
+{
+ if (IS_PTR (type) && !force)
+ return DCL_TYPE (type);
+
+ /* return the pointer depending on the storage class */
+ return PTR_TYPE (SPEC_OCLS (getSpec (type)));
+}
+
/*-----------------------------------------------------------------*/
/* 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;
left = geniCodeRValue (left, FALSE);
}
- return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
+ return geniCodeDerefPtr (geniCodeAdd (left,
+ right,
+ (getArraySizePtr(left) >= INTSIZE) ?
+ RESULT_TYPE_INT :
+ RESULT_TYPE_CHAR,
+ 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));
+ size,
+ (getArraySizePtr(left) >= INTSIZE) ?
+ RESULT_TYPE_INT :
+ RESULT_TYPE_CHAR);
/* 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);
if (IS_ITEMP (rv))
OP_SYMBOL(rv)->noSpilLoc = 1;
- geniCodeAssign (rOp, rv, 0);
+ geniCodeAssign (rOp, rv, 0, 0);
size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
if (IS_FLOAT (rvtype))
IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
ADDTOCHAIN (ic);
- geniCodeAssign (op, result, 0);
+ geniCodeAssign (op, result, 0, 0);
return rOp;
IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
ADDTOCHAIN (ic);
- (void) geniCodeAssign (op, result, 0);
+ (void) geniCodeAssign (op, result, 0, 0);
if (lvalue || IS_TRUE_SYMOP (op))
return op;
else
if (IS_ITEMP (rv))
OP_SYMBOL(rv)->noSpilLoc = 1;
- geniCodeAssign (rOp, rv, 0);
+ geniCodeAssign (rOp, rv, 0, 0);
size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
if (IS_FLOAT (rvtype))
IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
ADDTOCHAIN (ic);
- geniCodeAssign (op, result, 0);
+ geniCodeAssign (op, result, 0, 0);
return rOp;
IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
ADDTOCHAIN (ic);
- (void) geniCodeAssign (op, result, 0);
+ (void) geniCodeAssign (op, result, 0, 0);
if (lvalue || IS_TRUE_SYMOP (op))
return op;
else
/* geniCodeLeftShift - gen i code for left shift */
/*-----------------------------------------------------------------*/
operand *
-geniCodeLeftShift (operand * left, operand * right)
+geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
{
iCode *ic;
+ sym_link *resType;
- left = usualUnaryConversions (left);
ic = newiCode (LEFT_OP, left, right);
- IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
+
+ resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
+ IC_RESULT (ic) = newiTempOperand (resType, 0);
ADDTOCHAIN (ic);
return IC_RESULT (ic);
}
/*-----------------------------------------------------------------*/
/* geniCodeLogic- logic code */
/*-----------------------------------------------------------------*/
-operand *
+static operand *
geniCodeLogic (operand * left, operand * right, int op)
{
iCode *ic;
}
}
- ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
+ ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
ic = newiCode (op, left, right);
IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
op != NE_OP &&
op != AND_OP &&
op != OR_OP)
- ic->supportRtn = 1;
+ ic->supportRtn = 1;
ADDTOCHAIN (ic);
return IC_RESULT (ic);
}
+/*-----------------------------------------------------------------*/
+/* geniCodeLogicAndOr - && || operations */
+/*-----------------------------------------------------------------*/
+static operand *
+geniCodeLogicAndOr (ast *tree, int lvl)
+{
+ iCode *ic;
+ symbol *falseLabel = newiTempLabel (NULL);
+ symbol *trueLabel = newiTempLabel (NULL);
+ symbol *exitLabel = newiTempLabel (NULL);
+ operand *op, *result, *condition;
+
+ /* AND_OP and OR_OP are no longer generated because of bug-905492.
+ They can be reenabled by executing the following block. If you find
+ a decent optimization you could start right here:
+ */
+#if 0
+ if (0)
+ {
+ operand *leftOp, *rightOp;
+
+ leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
+ rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
+
+ return geniCodeLogic (leftOp, rightOp, tree->opval.op);
+ }
+#endif
+
+ /* generate two IFX for the '&&' or '||' op */
+
+ /* evaluate left operand */
+ condition = ast2iCode (tree->left, lvl + 1);
+ op = geniCodeRValue (condition, FALSE);
+
+ /* test left operand */
+ if (tree->opval.op == AND_OP)
+ ic = newiCodeCondition (op, NULL, falseLabel);
+ else /* OR_OP */
+ ic = newiCodeCondition (op, trueLabel, NULL);
+ ADDTOCHAIN (ic);
+
+ /* evaluate right operand */
+ condition = ast2iCode (tree->right, lvl + 1);
+ op = geniCodeRValue (condition, FALSE);
+
+ /* test right operand */
+ ic = newiCodeCondition (op, trueLabel, NULL);
+ ADDTOCHAIN (ic);
+
+ /* store 0 or 1 in result */
+ result = newiTempOperand (newCharLink(), 1);
+
+ geniCodeLabel (falseLabel);
+ geniCodeAssign (result, operandFromLit (0), 0, 0);
+ /* generate an unconditional goto */
+ geniCodeGoto (exitLabel);
+
+ geniCodeLabel (trueLabel);
+ geniCodeAssign (result, operandFromLit (1), 0, 0);
+
+ geniCodeLabel (exitLabel);
+
+ return result;
+}
+
/*-----------------------------------------------------------------*/
/* geniCodeUnary - for a a generic unary operation */
/*-----------------------------------------------------------------*/
/* move the value to a new Operand */
result = newiTempOperand (tree->right->ftype, 0);
- geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
+ geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
/* generate an unconditional goto */
geniCodeGoto (exitLabel);
geniCodeLabel (falseLabel);
false = ast2iCode (tree->right->right,lvl+1);
- geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
+ geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
/* create the exit label */
geniCodeLabel (exitLabel);
/* geniCodeAssign - generate code for assignment */
/*-----------------------------------------------------------------*/
operand *
-geniCodeAssign (operand * left, operand * right, int nosupdate)
+geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
{
iCode *ic;
sym_link *ltype = operandType (left);
sym_link *rtype = operandType (right);
- if (!left->isaddr && !IS_ITEMP (left))
+ if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
{
werror (E_LVALUE_REQUIRED, "assignment");
return left;
/*-----------------------------------------------------------------*/
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 */
operand *top = operandFromSymbol (argVals->sym);
/* clear useDef and other bitVectors */
OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
- geniCodeAssign (top, pval, 1);
+ geniCodeAssign (top, pval, 1, 0);
}
else
{
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);
/* if the min is not zero then we no make it zero */
if (min)
{
- cond = geniCodeSubtract (cond, operandFromLit (min));
+ cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
if (!IS_LITERAL(getSpec(operandType(cond))))
setOperandType (cond, UCHARTYPE);
}
/*-----------------------------------------------------------------*/
/* geniCodeArrayInit - intermediate code for array initializer */
/*-----------------------------------------------------------------*/
-static void
+static void
geniCodeArrayInit (ast * tree, operand *array)
{
iCode *ic;
tree->opval.op != '?' &&
tree->opval.op != CALL &&
tree->opval.op != IFX &&
+ tree->opval.op != AND_OP &&
+ tree->opval.op != OR_OP &&
tree->opval.op != LABEL &&
tree->opval.op != GOTO &&
tree->opval.op != SWITCH &&
case '/':
return geniCodeDivision (geniCodeRValue (left, FALSE),
- geniCodeRValue (right, FALSE));
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype));
case '%':
return geniCodeModulus (geniCodeRValue (left, FALSE),
- geniCodeRValue (right, FALSE));
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype));
case '*':
if (right)
return geniCodeMultiply (geniCodeRValue (left, FALSE),
- geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype));
else
return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
case '-':
- if (right)
+ if (right)
return geniCodeSubtract (geniCodeRValue (left, FALSE),
- geniCodeRValue (right, FALSE));
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype));
else
return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
case '+':
if (right)
return geniCodeAdd (geniCodeRValue (left, FALSE),
- geniCodeRValue (right, FALSE),lvl);
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype),
+ lvl);
else
return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
case LEFT_OP:
return geniCodeLeftShift (geniCodeRValue (left, FALSE),
- geniCodeRValue (right, FALSE));
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype));
case RIGHT_OP:
return geniCodeRightShift (geniCodeRValue (left, FALSE),
setOperandType (op, UCHARTYPE);
return op;
}
+ case AND_OP:
+ case OR_OP:
+ return geniCodeLogicAndOr (tree, lvl);
case '>':
case '<':
case LE_OP:
case GE_OP:
case EQ_OP:
case NE_OP:
- case AND_OP:
- case OR_OP:
/* different compilers (even different gccs) evaluate
- the two calls in a different order. to get the same
- result on all machines we've to specify a clear sequence.
+ the two calls in a different order. to get the same
+ result on all machines we've to specify a clear sequence.
return geniCodeLogic (geniCodeRValue (left, FALSE),
geniCodeRValue (right, FALSE),
tree->opval.op);
*/
{
- operand *leftOp, *rightOp;
+ operand *leftOp, *rightOp;
- rightOp = geniCodeRValue (right, FALSE);
- leftOp = geniCodeRValue (left , FALSE);
+ leftOp = geniCodeRValue (left , FALSE);
+ rightOp = geniCodeRValue (right, FALSE);
- return geniCodeLogic (leftOp, rightOp, tree->opval.op);
+ return geniCodeLogic (leftOp, rightOp, tree->opval.op);
}
case '?':
return geniCodeConditional (tree,lvl);
else
right = geniCodeRValue (right, FALSE);
- geniCodeAssign (left, right, 0);
+ geniCodeAssign (left, right, 0, 1);
return right;
}
case MUL_ASSIGN:
geniCodeAssign (left,
geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
FALSE),
- geniCodeRValue (right, FALSE),FALSE), 0);
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype)),
+ 0, 1);
case DIV_ASSIGN:
return
geniCodeAssign (left,
geniCodeDivision (geniCodeRValue (operandFromOperand (left),
FALSE),
- geniCodeRValue (right, FALSE)), 0);
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype)),
+ 0, 1);
case MOD_ASSIGN:
return
geniCodeAssign (left,
geniCodeModulus (geniCodeRValue (operandFromOperand (left),
FALSE),
- geniCodeRValue (right, FALSE)), 0);
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype)),
+ 0, 1);
case ADD_ASSIGN:
{
sym_link *rtype = operandType (right);
return geniCodeAssign (left,
geniCodeAdd (geniCodeRValue (operandFromOperand (left),
FALSE),
- right,lvl), 0);
+ right,
+ getResultTypeFromType (tree->ftype),
+ lvl),
+ 0, 1);
}
case SUB_ASSIGN:
{
geniCodeAssign (left,
geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
FALSE),
- right), 0);
+ right,
+ getResultTypeFromType (tree->ftype)),
+ 0, 1);
}
case LEFT_ASSIGN:
return
geniCodeAssign (left,
geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
,FALSE),
- geniCodeRValue (right, FALSE)), 0);
+ geniCodeRValue (right, FALSE),
+ getResultTypeFromType (tree->ftype)),
+ 0, 1);
case RIGHT_ASSIGN:
return
geniCodeAssign (left,
geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
,FALSE),
- geniCodeRValue (right, FALSE)), 0);
+ geniCodeRValue (right, FALSE)), 0, 1);
case AND_ASSIGN:
return
geniCodeAssign (left,
FALSE),
geniCodeRValue (right, FALSE),
BITWISEAND,
- operandType (left)), 0);
+ operandType (left)), 0, 1);
case XOR_ASSIGN:
return
geniCodeAssign (left,
FALSE),
geniCodeRValue (right, FALSE),
'^',
- operandType (left)), 0);
+ operandType (left)), 0, 1);
case OR_ASSIGN:
return
geniCodeAssign (left,
,FALSE),
geniCodeRValue (right, FALSE),
'|',
- operandType (left)), 0);
+ operandType (left)), 0, 1);
case ',':
return geniCodeRValue (right, FALSE);