+ }
+ IC_RESULT (ic) = newiTempOperand (resType, 1);
+
+ ADDTOCHAIN (ic);
+ return IC_RESULT (ic);
+}
+
+/*-----------------------------------------------------------------*/
+/* geniCodeDivision - gen intermediate code for division */
+/*-----------------------------------------------------------------*/
+operand *
+geniCodeDivision (operand * left, operand * right)
+{
+ iCode *ic;
+ int p2 = 0;
+ sym_link *resType;
+ sym_link *rtype = operandType (right);
+ sym_link *retype = getSpec (rtype);
+ sym_link *ltype = operandType (left);
+ sym_link *letype = getSpec (ltype);
+
+ resType = usualBinaryConversions (&left, &right);
+
+ /* if the right is a literal & power of 2 */
+ /* then make it a right shift */
+ if (IS_LITERAL (retype) &&
+ !IS_FLOAT (letype) &&
+ (p2 = powof2 ((unsigned long)
+ floatFromVal (right->operand.valOperand)))) {
+ ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
+ }
+ else
+ {
+ ic = newiCode ('/', left, right); /* normal division */
+ /* if the size left or right > 1 then support routine */
+ if (getSize (ltype) > 1 || getSize (rtype) > 1)
+ ic->supportRtn = 1;
+ }
+ IC_RESULT (ic) = newiTempOperand (resType, 0);
+
+ ADDTOCHAIN (ic);
+ return IC_RESULT (ic);
+}
+/*-----------------------------------------------------------------*/
+/* geniCodeModulus - gen intermediate code for modulus */
+/*-----------------------------------------------------------------*/
+operand *
+geniCodeModulus (operand * left, operand * right)
+{
+ iCode *ic;
+ sym_link *resType;
+ LRTYPE;
+
+ /* if they are both literal then we know the result */
+ if (IS_LITERAL (letype) && IS_LITERAL (retype))
+ return operandFromValue (valMod (left->operand.valOperand,
+ right->operand.valOperand));
+
+ resType = usualBinaryConversions (&left, &right);
+
+ /* now they are the same size */
+ ic = newiCode ('%', left, right);
+
+ /* if the size left or right > 1 then support routine */
+ if (getSize (ltype) > 1 || getSize (rtype) > 1)
+ ic->supportRtn = 1;
+ IC_RESULT (ic) = newiTempOperand (resType, 0);
+
+ ADDTOCHAIN (ic);
+ return IC_RESULT (ic);
+}
+
+/*-----------------------------------------------------------------*/
+/* geniCodePtrPtrSubtract - subtracts pointer from pointer */
+/*-----------------------------------------------------------------*/
+operand *
+geniCodePtrPtrSubtract (operand * left, operand * right)
+{
+ iCode *ic;
+ operand *result;
+ LRTYPE;
+
+ /* if they are both literals then */
+ if (IS_LITERAL (letype) && IS_LITERAL (retype))
+ {
+ result = operandFromValue (valMinus (left->operand.valOperand,
+ right->operand.valOperand));
+ goto subtractExit;
+ }
+
+ ic = newiCode ('-', left, right);
+
+ IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
+ ADDTOCHAIN (ic);
+
+subtractExit:
+ return geniCodeDivision (result,
+ operandFromLit (getSize (ltype->next)));
+}
+
+/*-----------------------------------------------------------------*/
+/* geniCodeSubtract - generates code for subtraction */
+/*-----------------------------------------------------------------*/
+operand *
+geniCodeSubtract (operand * left, operand * right)
+{
+ iCode *ic;
+ int isarray = 0;
+ sym_link *resType;
+ LRTYPE;
+
+ /* if they both pointers then */
+ if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
+ (IS_PTR (rtype) || IS_ARRAY (rtype)))
+ return geniCodePtrPtrSubtract (left, right);
+
+ /* if they are both literal then we know the result */
+ if (IS_LITERAL (letype) && IS_LITERAL (retype)
+ && left->isLiteral && right->isLiteral)
+ return operandFromValue (valMinus (left->operand.valOperand,
+ right->operand.valOperand));
+
+ /* if left is an array or pointer */
+ if (IS_PTR (ltype) || IS_ARRAY (ltype))
+ {
+ isarray = left->isaddr;
+ right = geniCodeMultiply (right,
+ operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
+ resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
+ }
+ else
+ { /* make them the same size */
+ resType = usualBinaryConversions (&left, &right);
+ }
+
+ ic = newiCode ('-', left, right);
+
+ IC_RESULT (ic) = newiTempOperand (resType, 1);
+ IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
+
+ /* if left or right is a float */
+ if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
+ ic->supportRtn = 1;
+
+ ADDTOCHAIN (ic);
+ return IC_RESULT (ic);
+}
+
+/*-----------------------------------------------------------------*/
+/* geniCodeAdd - generates iCode for addition */
+/*-----------------------------------------------------------------*/
+operand *
+geniCodeAdd (operand * left, operand * right,int lvl)
+{
+ iCode *ic;
+ sym_link *resType;
+ operand *size;
+ int isarray = 0;
+ LRTYPE;
+
+ /* if left is an array then array access */
+ if (IS_ARRAY (ltype))
+ return geniCodeArray (left, right,lvl);
+
+ /* if the right side is LITERAL zero */
+ /* return the left side */
+ if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
+ return left;
+
+ /* if left is literal zero return right */
+ if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
+ return right;
+
+ /* if left is an array or pointer then size */
+ if (IS_PTR (ltype))
+ {
+ isarray = left->isaddr;
+ // there is no need to multiply with 1
+ if (getSize(ltype->next)!=1) {
+ size = operandFromLit (getSize (ltype->next));
+ right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
+ }
+ resType = copyLinkChain (ltype);
+ }
+ else
+ { /* make them the same size */
+ resType = usualBinaryConversions (&left, &right);
+ }
+
+ /* if they are both literals then we know */
+ if (IS_LITERAL (letype) && IS_LITERAL (retype)
+ && left->isLiteral && right->isLiteral)
+ return operandFromValue (valPlus (valFromType (letype),
+ valFromType (retype)));
+
+ ic = newiCode ('+', left, right);
+
+ IC_RESULT (ic) = newiTempOperand (resType, 1);
+ IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
+
+ /* if left or right is a float then support
+ routine */
+ if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
+ ic->supportRtn = 1;
+
+ ADDTOCHAIN (ic);
+
+ return IC_RESULT (ic);
+