Fixed add, sub for sizeof == 2
[fw/sdcc] / src / SDCCcse.c
index fea12fb3cd48fc791264aa9d2a1a53e9ef113676..f1f91676390e9b37b5464ace1984b9c06fde63b6 100644 (file)
@@ -973,6 +973,7 @@ DEFSETFUNC(diCodeForSym)
 int constFold (iCode *ic, set *cseSet)
 {
     iCode *dic = NULL;
+    iCode *ldic= NULL;
     /* this routine will change
        a = b + 10;
        c = a + 10;
@@ -1006,6 +1007,16 @@ int constFold (iCode *ic, set *cseSet)
     if (!IS_OP_LITERAL(IC_RIGHT(dic)))
        return 0;
 
+    /* find the definition of the left operand
+       of dic.then check if this defined with a
+       get_pointer return 0 if the pointer size is
+       less than 2 (MCS51 specific) */
+    if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(dic),&ldic)))
+       return 0;
+
+    if (POINTER_GET(ldic) && getSize(operandType(IC_LEFT(ldic))) <= 1)
+       return 0;
+    
     /* it is if the operations are the same*/
     /* the literal parts need to be added  */
     IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));    
@@ -1097,6 +1108,20 @@ DEFSETFUNC(delGetPointerSucc)
     return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
 }    
 
+/*-----------------------------------------------------------------*/
+/* fixUpTypes - KLUGE HACK fixup a lowering problem                */
+/*-----------------------------------------------------------------*/
+static void fixUpTypes(iCode *ic)
+{
+       link *t1 = operandType(IC_LEFT(ic)) ,*t2;
+       /* for pointer_gets if the types of result & left r the
+          same then change it type of result to next */
+       if (IS_PTR(t1) &&
+           checkType(t2=operandType(IC_RESULT(ic)),t1) == 1) {
+               setOperandType(IC_RESULT(ic),t2->next);
+       }
+}
+
 /*-----------------------------------------------------------------*/
 /* cseBBlock - common subexpression elimination for basic blocks   */
 /*             this is the hackiest kludgiest routine in the whole */
@@ -1145,7 +1170,6 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
        /* if this is an assignment from true symbol
           to a temp then do pointer post inc/dec optimzation */
        if (ic->op == '=' && !POINTER_SET(ic) &&
-           IS_TRUE_SYMOP(IC_RIGHT(ic)) && IS_ITEMP(IC_RESULT(ic)) &&
            IS_PTR(operandType(IC_RESULT(ic)))) {
            ptrPostIncDecOpt(ic);
        }
@@ -1225,6 +1249,8 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
        if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) {
            setOperandType(IC_LEFT(ic),
                           aggrToPtr(operandType(IC_LEFT(ic)),FALSE));
+           fixUpTypes(ic);
+
        }
        if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) {
            setOperandType(IC_RESULT(ic),
@@ -1332,6 +1358,9 @@ int cseBBlock ( eBBlock *ebb, int computeOnly,
              IS_ITEMP(IC_RESULT(ic))               &&
            ! computeOnly) {
            applyToSet (cseSet,findPrevIc,ic,&pdic);
+           if (pdic && checkType(operandType(IC_RESULT(pdic)),
+                                 operandType(IC_RESULT(ic))) != 1)
+                   pdic = NULL;
        } 
        
        /* if found then eliminate this and add to*/