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
/*-----------------------------------------------------------------*/
/* perform "usual unary conversions" */
/*-----------------------------------------------------------------*/
-operand *
+static operand *
usualUnaryConversions (operand * op)
{
if (IS_INTEGRAL (operandType (op)))
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);
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',
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)
{
iCode *ic;
+ left = usualUnaryConversions (left);
ic = newiCode (LEFT_OP, left, right);
IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
ADDTOCHAIN (ic);
return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
case '-':
- if (right)
+ if (right)
return geniCodeSubtract (geniCodeRValue (left, FALSE),
geniCodeRValue (right, FALSE));
else
case RIGHT_OP:
return geniCodeRightShift (geniCodeRValue (left, FALSE),
geniCodeRValue (right, FALSE));
- case CAST:
+ case CAST:
#if 0 // this indeed needs a second thought
{
operand *op;
-
+
// let's keep this simple: get the rvalue we need
op=geniCodeRValue (right, FALSE);
// now cast it to whatever we want
return NULL;
case CRITICAL:
- geniCodeCritical (tree, lvl);
+ geniCodeCritical (tree, lvl);
}
return NULL;