/*-----------------------------------------------------------------*/
/* geniCodeMultiply - gen intermediate code for multiplication */
/*-----------------------------------------------------------------*/
-operand *geniCodeMultiply (operand *left, operand *right)
-{
+operand *geniCodeMultiply (operand *left, operand *right,bool ptrSizeCalculation)
+{
iCode *ic ;
int p2 = 0;
+ int saveOption;
sym_link *resType ;
LRTYPE ;
/* if they are both literal then we know the result */
- if (IS_LITERAL(letype) && IS_LITERAL(retype))
- return operandFromValue (valMult(left->operand.valOperand,
- right->operand.valOperand));
-
- resType = usualBinaryConversions(&left, &right);
+ if (IS_LITERAL(letype) && IS_LITERAL(retype))
+ return operandFromValue (valMult(left->operand.valOperand,
+ right->operand.valOperand));
+
+
+ //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
+ if ((ptrSizeCalculation)&&(1==getSize(rtype))&&
+ (1==getSize(ltype))) {
+ saveOption = options.ANSIint;
+ options.ANSIint = 0;
+ resType = usualBinaryConversions(&left, &right);
+ ltype = operandType(left);
+ rtype = operandType(right);
+ SPEC_SHORT(getSpec(resType)) = 0;
+ options.ANSIint = saveOption;
+ }
+ else
+ resType = usualBinaryConversions(&left, &right);
/* if the right is a literal & power of 2 */
/* then make it a left shift */
- if (IS_LITERAL(retype) && !IS_FLOAT(letype) &&
- (p2 = powof2 ((unsigned long)floatFromVal(right->operand.valOperand))))
- ic = newiCode(LEFT_OP, left,operandFromLit(p2)); /* left shift */
+ /*If we are computing ptr size then normal multiplication*/
+ /*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 as 1 byte muldiv*/
+ if (IS_LITERAL(retype) && !IS_FLOAT(letype) &&
+ !((ptrSizeCalculation)&&(getSize(resType)!=getSize(ltype))&&(1==port->muldiv.native_below))&&
+ (p2 = powof2 ((unsigned long)floatFromVal(right->operand.valOperand))))
+ {
+ if((ptrSizeCalculation)&&(getSize(resType)!=getSize(ltype))){
+ /* LEFT_OP need same size for left and result, */
+ left = geniCodeCast(resType,left,TRUE);
+ ltype = operandType(left);
+ }
+ ic = newiCode(LEFT_OP, left,operandFromLit(p2)); /* left shift */
+ }
else {
ic = newiCode('*',left,right); /* normal multiplication */
/* if the size left or right > 1 then support routine */
/* if left is an array or pointer */
if ( IS_PTR(ltype) || IS_ARRAY(ltype) ) {
- isarray = left->isaddr ;
- right = geniCodeMultiply (right,
- operandFromLit(getSize(ltype->next)));
- resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype);
+ isarray = left->isaddr ;
+ right = geniCodeMultiply (right,
+ operandFromLit(getSize(ltype->next)),TRUE);
+ resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype);
}
else { /* make them the same size */
resType = usualBinaryConversions(&left, &right);
return right ;
/* if left is an array or pointer then size */
- if (IS_PTR(ltype)) {
+ if (IS_PTR(ltype)) {
+
+ isarray = left->isaddr;
+ size =
+ operandFromLit(getSize(ltype->next));
- isarray = left->isaddr;
- size =
- operandFromLit(getSize(ltype->next));
- if (getSize(ltype) > 1 && (getSize(rtype) < INTSIZE))
- {
- right = geniCodeCast(INTTYPE,right,TRUE);
- }
- right = geniCodeMultiply (right ,size);
+ right = geniCodeMultiply (right ,size,(getSize(ltype)!= 1));
resType = copyLinkChain(ltype);
}
}
/* array access */
- right = usualUnaryConversions(right);
right = geniCodeMultiply(right,
- operandFromLit(getSize(ltype->next)));
+ operandFromLit(getSize(ltype->next)),TRUE);
/* we can check for limits here */
if (isOperandLiteral(right) &&
rv->noSpilLoc = 1;
geniCodeAssign(rOp,rv,0);
-
+
size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
- ic = newiCode('+',rv,operandFromLit(size));
+ if (IS_FLOAT(rvtype))
+ ic = newiCode('+',rv,operandFromValue(constFloatVal("1.0")));
+ else
+ ic = newiCode('+',rv,operandFromLit(size));
+
IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
ADDTOCHAIN(ic);
size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
- ic = newiCode('+',rop,operandFromLit(size));
+ if (IS_FLOAT(roptype))
+ ic = newiCode('+',rop,operandFromValue(constFloatVal("1.0")));
+ else
+ ic = newiCode('+',rop,operandFromLit(size));
IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
ADDTOCHAIN(ic);
rv->noSpilLoc = 1;
geniCodeAssign(rOp,rv,0);
-
+
size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
- ic = newiCode('-',rv,operandFromLit(size));
+ if (IS_FLOAT(rvtype))
+ ic = newiCode('-',rv,operandFromValue(constFloatVal("1.0")));
+ else
+ ic = newiCode('-',rv,operandFromLit(size));
+
IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
ADDTOCHAIN(ic);
size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
- ic = newiCode('-',rop,operandFromLit(size));
+ if (IS_FLOAT(roptype))
+ ic = newiCode('-',rop,operandFromValue(constFloatVal("1.0")));
+ else
+ ic = newiCode('-',rop,operandFromLit(size));
IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
ADDTOCHAIN(ic);
{
iCode *ic;
+ /* Operands must be promoted to int, according to ISO. */
+ if (getSize(operandType(right)) < INTSIZE)
+ {
+ right = geniCodeCast(INTTYPE,right,TRUE);
+ }
+
/* Note that we don't use the usual binary conversions for the
* shift operations, in accordance with our ANSI friends.
*/
{
iCode *ic;
+ /* Operands must be promoted to int, according to ISO. */
+ if (getSize(operandType(right)) < INTSIZE)
+ {
+ right = geniCodeCast(INTTYPE,right,TRUE);
+ }
+
/* Note that we don't use the usual binary conversions for the
* shift operations, in accordance with our ANSI friends.
*/
case '*':
if ( right )
return geniCodeMultiply (geniCodeRValue(left,FALSE),
- geniCodeRValue(right,FALSE));
+ geniCodeRValue(right,FALSE),FALSE);
else
return geniCodeDerefPtr (geniCodeRValue(left,FALSE));
geniCodeAssign(left,
geniCodeMultiply(geniCodeRValue (operandFromOperand(left),
FALSE),
- geniCodeRValue(right,FALSE)),0);
+ geniCodeRValue(right,FALSE),FALSE),0);
case DIV_ASSIGN:
return